Javase | StringBuffer、StringBuilder

思考:进行字符串的频繁拼接,会有什么问题?

  • 我们在实际的开发中,如果需要进行字符串的频繁拼接,会有什么问题?

  • Java中的字符串不可变的,一经创建,便不可修改,每一次拼接都是产生新的字符串,这样会占用大量的的方法区内存,同时会造成内存空间的浪费

    例子如:

      String s = "abc";
      s = s +"hello";
      /*
       就以上代码就导致“方法区”中的“字符串常量池”中创建了三个“字符串对象”,
       分别为: "abc"、“hello”、“abchello”。
    
       此番操作占用大量的方法区内存,同时也造成内存空间的浪费
      */
    
  • 如果要进行大量的字符串的“拼接操作”,可以用JDK自带的:
    Java.lagn.StringBuffer(字符串缓冲区对象)
    StringBufferString底层都是byte[ ]数组,但String底层是是final修饰的byte[ ]数组,是不可变的。而StringBuffer底层是可变的byte[ ]数组,自然是可追加的,是可变的。)

思考:为什么StringBuffer是可变的?StringBuffer是可追加字符串的?

  • 首先,StringBufferString底层都是byte[ ]数组,但String的的byte[ ]数组有final 关键字修饰,这也是它是 不可变的 的原因,这导致了String字符串一经创建,便不可修改
  • StringBuffer ( 字符串缓冲区 对象 )的 byte[ ]数组没有final 关键字修饰的,是可对数组进行扩容的,因而StringBuffer可变的,同时可通过append( )方法向StringBuffer中追加字符串。

StringBuffer

  • StringBuffer字符串缓冲区(对象),底层实际上是一个 byte[ ]数组
    StringBuffer中放字符串,实际上是放到byte数组中。StringBuffer的byte[ ]数组是没有final关键字修饰的,数组是可扩容的,因而可以通过append( Object o )方法StringBuffer追加字符串。

  • StringBuffer的默认初始化容量16。即底层的byte[ ]数组的初始化容量/长度为16

  • StringBuffer可用append( Object o )方法进行字符串数据的追加。在追加时,如果byte数组满了,会自动扩容

  • StringBuilder的方法中都有synchronized关键字修饰。表示StringBuffer在多线程环境下运行安全 的。

  • 拓展:
    其实String底层也是byte[ ]数组,但其前面有一个final关键字修饰,是不可变的,导致字符串也是不可变一经创建,变不可修改。
    StringBuffer底层是一个可变的byte[ ]数组,自然其是可变的,可追加字符串数据的。

    例子如:

     		/*
              创建一个(默认)初始化容量为16的byte[]数组(字符串缓冲区对象)
              “符串缓冲区”底层为: byte[]数组,可实现字符串的追加,而不会因为“字符串对象”的频繁		  增加而占用大量的内存空间。
             */
            StringBuffer stringBuffer = new StringBuffer();
    
            /*
              往“字符串缓冲区”中追加字符串 (因为其底层是byte[]数组,避开了String不可变的特		  性,能追加字符串数据)
             */
            // append方法底层在进行追加的时候,如果byte数组满了,会自动扩容。
            stringBuffer.append("a");
            stringBuffer.append("b");
            stringBuffer.append("c");
            stringBuffer.append(3.14);
            stringBuffer.append(true);
            stringBuffer.append(100L);
    
            //StringBuffer重写了toString()方法,输出的StringBuffer中的字符串本身
            System.out.println(stringBuffer); //abc3.14true100
    

思考:如何优化StringBuffer的性能?

  • 在创建 StringBuffer 的时候尽可能给定一个较大的初始化容量。较大的初始化容量能减少底层数据的扩容次数提高StringBuffer的性能

  • 给一个合适的初始化容量,可以提高程序的执行效率

    例子如:

       //指定初始化容量的StringBuffer对象(字符串缓冲区对象)
       //创建指定字节数组容量为100的StringBuffer对象
       /**
       *  给一个合适的初始化容量,可以提高程序的执行效率 (优化StringBuffer的性能)
       */
       StringBuffer stringBuffer = new StringBuffer(100);
       stringBuffer.append("apple");
       stringBuffer.append("hello");
       stringBuffer.append(123);
    
       //输出StringBuffer对象
       System.out.println(stringBuffer); //applehello123
    

StringBuilder

  • StringBuilder字符串生成器(对象),底层也是是一个 byte[ ]数组
  • StringBuilder中放字符串,实际上是也是存放到byte数组中。
  • StringBuilder初始化容量是16,即底层的byte[ ]数组的初始化容量/长度为16
  • StringBuffer可用append( Object o )方法进行字符串数据的追加。在追加时,如果byte数组满了,会自动扩容
  • StringBuilder的方法中都没有 synchronized关键字修饰。表示StringBuilder在多线程环境下运行不安全 的。

StringBuffer 和 StringBuilder的区别?

  • StringBuilder的方法中 都“有”synchronized 关键字修饰。表示StringBuffer在多线程环境下运行安全 的。
    StringBuilder的方法中 都“没有”synchronized 关键字修饰。表示StringBuilder在多线程环境下运行不安全 的。
  • StringBuffer线程安全 的,StringBuilder非线程安全 的。

猜你喜欢

转载自blog.csdn.net/m0_70720417/article/details/132797501