String 、StringBuffer、StringBuilder 三者的异同(重点面试题)

简介: String 、StringBuffer、StringBuilder 三者的异同(重点面试题)

String 、StringBuffer、StringBuilder 三者的异同。

一:


字符序列可不可变

String     不可变

StringBuffer     可变

StringBuilder      可变

二:


StringBuffer 和 StringBuilder 的一些区别

StringBuffer 线程安全,效率低。底层为char [] , jdk1.0。

StringBuilder 线程不安全,使用效率高 底层为 char[]  , jdk 5.0 新增。

三 :思考为什么String是不可变的 StringBuffer 和 StringBUilders是可变的?


我们可以通过查看 以上三者的源码来分析。


String:

image.png



StringBuffer:

image.png



StringBuilders:

image.png



我们可以通过上面的三个底层源码可以看到三者都是用char[ ]来存储,为什么就 String 是不可变的呢? 我相信细心的小伙伴已经发现了 ,就 String 有 final ,则String是不可以变的。(如果有小伙伴对 final 不是很了解,我过几天会总结一下final的知识点。)


上面虽然简述了为什么可变不可变的原理,但是面试题可没上面几句简单,所以下面就是正真的重点!!!仔细看!!!


我们先进行源码的分析:


String str = new String(); //char[0]
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};

我们能知道这个是String的创建方法。


StringBuffer stringBuffer = new StringBuffer();

接下来我们查看一下StringBuffer的底层源码:

image.png



再查看super:

image.png



在查看value:


image.png


从源码我们能知道 StringBuffer 在创建一个新空间时,是首先构造一个字符串生成器,其中不包含字符,初始容量为16个字符。


StringBuffer stringBuffer = new StringBuffer();
//相当于底层创建了一个长度为16 char[] 数组
stringBuffer.append('a'); //value[0] = 'a';
stringBuffer.append('b'); //value[1] = 'b';
stringBuffer.append('c'); // value[2] = 'c';

当我们使用:


StringBuffer stringBuffer = new StringBuffer("abc");

我们查看底层源码:

image.png



我们能知道他是会创建一个 str.length() + 16 的数组长度。


StringBuffer stringBuffer = new StringBuffer("abc");
//char [] value = new char ["abc".length() + 16]

通过上述对源码的查询我们能知道StringBuffer之所以可变是因为他有大量的数组空间,我们可以通过在数组上修改通过对字符串的修改!!!


这样我们就正真的知道了为啥 StringBuffer 是可以变的了(StringBuilders和StringBuffer 的结构是相同的,上述结论也符合StringBuilders)


拓展一:


我们接下来要对StringBuffer的可变进行一些问题的延申:


我们通过上述源码分析我们能知道因为StringBuffer对char[] 数组的增大才可以使字符串变成可变性,一般情况StringBuffer初始话就比字符串长度多16个,如果我们一直对字符串进行添加处理直到超过初始化定义的长度会怎么办呢???


是会溢出还是会有一些解决办法呢???


我们可以在对源码进行分析:

image.png





这段源码的作用就是对添加后的字符串长度是否超过底层数组的长度进行一个判断,如果超过原来的底层数组就会执行newCapacity这个函数。接下来我们再来查看这个函数的源码:

image.png



通过对这个源码的分析我们能知道:这个是创建一个原来长度两倍加+2的长度的数组。


再来一起分析上面的几个代码我们可以知道如果原来的数组容量不够的情况下,我们会创建一个为原来长度两倍加2的一个新数组,再把原来的数组内容复制到现在这个数组中,并且在进行判断添加后的数组是否能大于添加后的长度,如果还是达不到则继续创建新的更大的数组,直到能大于目前添加后字符串的长度为止。



拓展二:


String、StringBuffer 和 StringBuilders三者的效率比较。


我们可以通过下面执行的代码来判断一下三者的执行效率:


package StringMoth;
public class demo3 {
    public static void main(String[] args) {
        long start_time = 0L;
        long end_time = 0L;
        String text = "";
        StringBuffer stringBuffer = new StringBuffer("");
        StringBuilder stringBuilder = new StringBuilder("");
        //开始对比
        start_time = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            stringBuffer.append(String.valueOf(i));
        }
        end_time = System.currentTimeMillis();
        System.out.println("Buffer的执行时间为:"+(end_time-start_time));
        start_time = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            stringBuilder.append(String.valueOf(i));
        }
        end_time = System.currentTimeMillis();
        System.out.println("Builder的执行时间为:"+(end_time-start_time));
        start_time = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            text = text + i;
        }
        end_time = System.currentTimeMillis();
        System.out.println("String的执行时间为:"+(end_time-start_time));
    }
}

输出结果:

image.png



我们能直到StringBuilders的效率是最高的,Buffer其次而String是效率最低的。


我们通过上面介绍的底层原理我们能知道String是不可变性的,如果添加一个新的字符串他则会开辟一个新的空间,然后把新的字符串放进这个新的地址中,因为每一次添加Sting都会开辟一个新的空间,所以会导致String的效率会很慢。


而Buffer和Builders则不同,它们都有多余的数组空间,在字符串长度不大于原数组长度时不会开辟新的空间,而是添加到空余的数组里面,这样就会使其效率高的很多!


而Builders是没有锁的,它可以同时进行多个操作,而Buffer是有锁的,只能同时进行一个操作,导致效率没有Builders的效率高。(这个地方我不是很确定,如果有大佬觉得错了希望能指正一下,我下去我也在查查别的资料!!)



目录
打赏
0
0
0
0
5
分享
相关文章
|
20天前
|
String StringBuffer StringBuilder 区别详解与对比分析
本文详细解析了Java中String、StringBuffer和StringBuilder的区别,从可变性、线程安全性和性能三个方面进行对比,并结合具体应用场景分析了三者的适用范围。通过性能测试示例展示了它们在字符串拼接时的效率差异,同时提供了实际代码案例帮助理解。总结指出,String适合少量操作或线程安全场景,StringBuffer适用于多线程环境,而StringBuilder则在单线程下性能最优。开发者应根据需求选择合适的类以优化程序性能。文末还附有相关面试资料供参考。
73 2
|
9月前
|
String、StringBuffer 和 StringBuilder 的区别
【10月更文挑战第21天】String、StringBuffer 和 StringBuilder 都有各自的特点和适用场景。了解它们之间的区别,可以帮助我们在编程中更合理地选择和使用这些类,从而提高程序的性能和质量。还可以结合具体的代码示例和实际应用场景,进一步深入分析它们的性能差异和使用技巧,使对它们的理解更加全面和深入。
337 57
String、StringBuffer、StringBuilder的区别
String 由 char[] 数组构成,使用了 final 修饰,对 String 进行改变时每次都会新生成一个 String 对象,然后把指针指向新的引用对象。 StringBuffer可变并且线程安全;有一定缓冲区容量,字符串大小没超过容量,不会重新分配新的容量,适合多线程操作字符串; StringBuiler可变并且线程不安全。速度比StringBuffer更快,适合单线程操作字符串。 操作少量字符数据用 String;单线程操作大量数据用 StringBuilder;多线程操作大量数据用 StringBuffer
String、StringBuffer、StringBuilder的区别
这篇文章讨论了Java中String、StringBuffer和StringBuilder的区别。String是不可变的,每次操作都会产生新的对象,效率低且浪费内存。StringBuilder可以在原字符串基础上进行操作,不开辟额外内存,弥补了String的缺陷。StringBuffer和StringBuilder类似,但StringBuffer的方法是线程安全的。文章还列举了StringBuffer的常用方法,并提供了使用示例代码。最后总结了这三者的主要区别。
String、StringBuffer、StringBuilder的区别
(StringBuffer和StringBuilder)以及回文串,字符串经典习题
(StringBuffer和StringBuilder)以及回文串,字符串经典习题
95 5
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
30 0
|
4月前
|
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
111 11
|
4月前
|
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、&quot;+&quot;操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
107 9
课时44:String类对象两种实例化方式比较
本次课程的主要讨论了两种处理模式在Java程序中的应用,直接赋值和构造方法实例化。此外,还讨论了字符串池的概念,指出在Java程序的底层,DOM提供了专门的字符串池,用于存储和查找字符串。 1.直接赋值的对象化模式 2.字符串池的概念 3.构造方法实例化

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问