常用类(2)StringBuffer与StringBuilder

1、概述

java.lang.StringBuffer代表可变的字符序列 ,可以对字符 串内容进行增删改,此时不会产生新的对象。

StringBuilder代表也是可变的字符序列,可以对字符串内容进行增删改,此时不会产生新的对象。

StringBuffer的源码截图:

 

StringBuilder的源码截图:

相比String类的  private final byte[] value; 就是Stringbuffer和StringBuilder都是可变的字符序列,它们都继承了AbstractStringBuffer,而这个抽象类一个byte[ ] value(不是final的)来存储字符串用的。

首先来一道面试常问的题:

2、String、StringBuffer、StringBuilder的异同?

String:不可变的字符序列:底层使用char[ ]存储

StringBuffer:可变的字符序列:线程是安全的,效率低,底层是使用char[ ]存储的

StringBuilder:可变的字符序列:线程也是不安全的,效率高,底层使用char [ ] 存储的

3、源码解析

三者的源码分析

String str1 = new String(); 相当于char [ ] value = new char[0]

String str2 = new String("abc"); 相当于char [ ] value = new char[ ]{'a','b','c'}

StringBuffer sber1 = new StringBuffer(); 底层是默认帮你创建一个长度16的字符数组,char [ ] value = new char[16]

   

父类的有参构造方法:

StringBuffer sber2 = new StringBuffer("abc"); 底层是默认帮你创建一个所创建的字符串长度 + 16 ,char [ ] value = new char [ "abc".length +16]

父类的有参构造方法:

1、这里就会有疑问了???,要是创建了个"abc"的StringBuffer的字符串,我们在输出其长度,length()会是19还是3??

StringBuffer stringBuffer = new StringBuffer("abc");
System.out.println(stringBuffer.length());

 答案是3,其中查看源码在使用debug模式可以看出是,它把str="abc“,在使用str.length;修改了父类的AbstractStringbuilder的count的值,修改成3.

在查看count的解释时,以及length()方法:被使用的used

获取长度是被使用的

2、还有一个疑问就是,添加时数组的底层不足以容下???不会数组越界???

其实就是底层扩容数组

当超过默认大小后,会创建一个更大的数组【创建(扩容原来的容量)*2 + 2】无参构造创建时,原本的容量是16,超过后扩容是34,并将原先的数组内容复制过来,再丢弃旧的数组。

源码通过debug过程:

StringBuilder和StringBuffer是一样的,方法内容。只是方法上加了synchronized同步,解决线程安全问题。

4、StringBuffer的常用方法

方法原型 作用及含义
StringBuffer append(xxx) 提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end) 删除指定下标的位置的内容
StringBuffer replace(int start, int end, String str) 把[start,end)下标的位置替换为str
StringBuffer insert(int offset, xxx) 在指定下标的位置插入xxx
StringBuffer reverse() 把当前字符序列逆转
public int indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引
public int length() 返回字符串的长度
public char charAt(int n ) 返回该索引下的字符
public void setCharAt(int n ,char ch) 把ch字符设置到字符串中指定下标位置

当append和insert时,如果原来value数组长度不够,可扩容

简单总结起来就是   增【append()】   删 【delete()】  改 【 setcharAt(int n)】  查 【 charAt(int n)】 插入 【 insert(int index,xxx)】

5、String、StringBuffer、StringBuilder的效率对比

代码演示:

package day02;

import org.junit.Test;
public class StringMain {
    @Test
    public void test01(){
            long startTime = 0L;
            long endTime = 0L;
            String text = "";
            StringBuffer buffer = new StringBuffer("");
            StringBuilder builder = new StringBuilder("");
            //开始对比
            startTime = System.currentTimeMillis();
            for (int i = 0; i < 20000; i++) {
                buffer.append(String.valueOf(i));
            }
            endTime = System.currentTimeMillis();
            System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
            startTime = System.currentTimeMillis();
            for (int i = 0; i < 20000; i++) {
                builder.append(String.valueOf(i));
            }
            endTime = System.currentTimeMillis();
            System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
            startTime = System.currentTimeMillis();
            for (int i = 0; i < 20000; i++) {
                text = text + i;
            }
            endTime = System.currentTimeMillis();
            System.out.println("String的执行时间:" + (endTime - startTime));
    }
}

输出:

StringBuffer的执行时间:10
StringBuilder的执行时间:4
String的执行时间:223

清楚的看见就是String是最慢的,而StringBuffer是第二(它保证了线程的安全,所以比StringBuilder慢)StringBuilder是最快的。

效率高到低:StringBuilder  > StringBuffer > String

面试题:

String str = null;
StringBuffer sb = new StringBuffer();
sb.append(str);
System.out.println(sb.length());//
System.out.println(sb);//
StringBuffer sb1 = new StringBuffer(str);
System.out.println(sb1);

输出是?

4

null

报错

查看源码才知道:

猜你喜欢

转载自blog.csdn.net/weixin_43725517/article/details/112849130