• String、StringBuilder、StringBuffer的爱恨情仇


    第三阶段 JAVA常见对象的学习

    StringBuffer和StringBuilder类

    (一) StringBuffer类的概述

    (1) 基本概述

    下文以StringBuffer为例

    前面我们用字符串做拼接,比较耗时并且也耗内存(每次都会构造一个新的string对象),而这种拼接操作又是比较常见的,为了解决这个问题,Java就提供了两个字符串缓冲区类。StringBuffer和StringBuilder供我们使用。

    简单比较:

    String 长度大小不可变

    StringBuffer 长度可变、线程安全、速度较慢

    StringBuilder 长度可变、线程不安全、速度最快

    -----------------------------------------------------------------------------------------------------------------

    解释:

    1. 在执行速度方面的比较:StringBuilder > StringBuffer

    2. StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。

    3. StringBuilder:线程非安全的

      StringBuffer:线程是安全的(synchronized关键字进行修饰)

    当我们在字符串缓冲区被多个线程使用时,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。

    对于三者使用的总结:

    1.如果要操作少量的数据用 = String
    2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
    3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

    (2) StringBuffer的构造方法

    //无参构造方法
    StringBuffer()
        
    //指定容量的字符串缓冲区对象
    StringBuffer(int size)
        
    //指定字符串内容的字符串缓冲区对象
    StringBuffer(String str)
    

    (二) StringBuffer 类的功能

    (1) 添加功能

    //可以把任意类型添加到字符串缓冲区里,并且返回字符串缓冲区本身(this)
    public StringBuffer append (String str)
    
    //在offset位置把任意类型的数据插入到字符串缓冲区中,并且返回字符串缓冲区本身(this)
    public StringBuffer insert(int offset,String str)
    

    (2) 删除功能

    //删除指定位置的字符,并且返回本身
    public StringBuffer deleteCharAt(int index)
    
    //删除从指定位置开始指定位置结束的内容,并且返回本身
    public StringBuffer delete(int start, int end) 
    

    (3) 替换功能

    //从start到end用str代替
    public StringBuffer replace(int start,int end,String str)
    

    (4) 反转功能

    //Eg: 好你界世 → 世界你好
    public StringBuffer reverse()
    

    (5) 截取功能

    //从start位置开始截取,取以后字符串,但不返回本身,原数据不影响
    public String substring(int start)
    
    //截取start到end之间的字符串
    Publci Stirng substring(int start, int end)
    

    (三) String 和 StringBuffer 类相互转换

    (1) 转换原因:

    String → StringBuffer 是为了使用后者的功能

    StringBuffer → String 可能需要后者的类型

    (2) 转换方式

    ※ String → StringBuffer

    String s = “Hello”
    
    //通过构造方法
    StringBuffer a = new StringBuffer(s);
    
    //通过append()方法
    
    StringBuffer a = new StringBuffer();
    a.append(s);
    

    ※ StringBuffer → String

    StringBuffer buffer = new StringBuffer(“java”)
    
    //通过构造方法
    String str = new String (buffer);
    
    //通过toString()方法
    String str = buffer.toString();
    
    

    (四) “+” 和 StringBuilder 类的爱恨情仇

    首先java并不支持运算符重载。

    (String类中的 “+”“+=”是java中仅有的两个重载过的运算符)

    所以我们可以通过“+”符号 将多个字符串进行拼接

    将这段代码利用 javap -c filename 反编译

    我们可以看到代码被编译器自动优化成使用StringBuilder方式拼接

    运行效率得到了保证

    img

    下面一个案例 数组拼接成指定格式的字符串 代码中使用了循环语句

    //在循环中通过String拼接字符串
    public class StringBuilderDemo {
       public static void main(String[] args) {
           String[] arr = {"Hello", "World", "!!!"};
           String s1 = arrayToString(arr);
           System.out.println(s1);
       }
    
       public static String arrayToString(String[] arr) {
           String s = "";
    
           s += "[";
           for (int x = 0; x < arr.length; x++) {
               if (x == arr.length - 1) {
                   s += arr[x];
               } else {
                   s += arr[x];
                   s += ", ";
               }
           }
           s += "]";
           return s;
       }
    }
    //运行结果
    [Hello, World, !!!]
    

    使用String方式进行拼接,我们反编译可以看到,StringBuilder被创建在循环的内部,这意味着每循环一次就会创建一次StringBuilder对象,这可是一个糟糕的事情。

    img

    //在循环中使用StringBuilder拼接字符串
    public class StringBuilderDemo2 {
        public static void main(String[] args) {
            String[] arr = {"Hello", "World", "!!!"};
            String s1 = arrayToString(arr);
            System.out.println(s1);
        }
    
        public static String arrayToString(String[] arr) {
            StringBuilder s = new StringBuilder();
            s.append("[");
            for (int x = 0; x < arr.length; x++) {
                if (x == arr.length - 1) {
                    s.append(arr[x]);
                } else {
                    s.append(arr[x]);
                    s.append(", ");
                }
            }
            s.append("]");
            return s.toString();
        }
    }
    //运行结果
    [Hello, World, !!!]
    

    使用StringBuilder方式进行拼接,反汇编代码,可以看到,不仅循环部分的代码更为简洁,而且它只生成了一个StringBuilder对象。显式的创建StringBuilder对象还允许你预先为其指定大小。可以避免多次重新分配缓冲。

    总结:

    如果字符串操作比较简单,就可以使用“+”运算符操作,编译器会为你合理的构造出最终的字符串结果

    如果使用循环语句 最好自己手动创建一个StringBuilder对象,用它来构最终结果

    结尾:

    如果内容中有什么不足,或者错误的地方,欢迎大家给我留言提出意见, 蟹蟹大家 !_

    如果能帮到你的话,那就来关注我吧!(系列文章均会在公众号第一时间更新)

    在这里的我们素不相识,却都在为了自己的梦而努力 ❤

    一个坚持推送原创Java技术的公众号:理想二旬不止

    img

  • 相关阅读:
    在下拉框中选择数据
    代码添加批处理类
    重置用户状态(初始化用户)
    当前窗口控制(显示、隐藏、破坏)
    窗体分隔符实现
    使用USB移动硬盘 遭遇 "Windows无法为Volume加载安装程序。请于硬件供应商联系,寻求协助" 错误,“灰鸽子”后遗症的处理
    使用IDL创建TypeLib(.tlb)文件
    ngrep使用方法
    常用的正则表达式
    治疗鼻炎的药
  • 原文地址:https://www.cnblogs.com/ideal-20/p/11050195.html
Copyright © 2020-2023  润新知