String、Stringbuilder、StringBuffer
◆ ◆ ◆ ◆
这三个的比较会被经常问到,常常跟优化沾边,一般准备过的同学都不会有太大问题。但是在小明同学工作一年跳槽,去面试阿里的时候,被一个面试官埋了个小坑,至今印象深刻。
String
◆ ◆ ◆ ◆
三个基本特点:
1.不变性:String对象一旦生成,则不能再对它进行改变。String的这个特性可以泛化成不变(immutable)模式,即一个对象的状态在对象被创建后就不再发生变化。主要作用在于一个对象需要被多进程共享,并且频繁访问时,可以省略同步和锁等待时间,从而增加系统性能
2.针对常量池的优化:当两个String对象有用相同的值时,他们只引用常量池中的同一个拷贝。当一个字符串反复出现时,可以大幅度节省内存空间。
如以上程序,我们很容易直到结果是true,false,true.具体的内存分配方式如下图:
3.类的final化:即不可能有任何子类,会提高安全性。
StringBuffer和StringBuilder
◆ ◆ ◆ ◆
由于String对象不可变,所以在修改操作时,会频繁创建新的对象,性能相对较差,于是就产生了StringBuffer和StringBuilder,如:
StringBuilder str = new StringBuilder(1024);
str.append("aaa");
str.append("bbb");
str.append("ccc");
其中str对象始终是一个。
StringBuffer和StringBuilder的差别就是,StringBuffer是线程安全的
StringBuilder是非线程安全的
需要关注的是,由于它们的对象是可变的,在创建的时候最好先预估量级,赋初值,避免一直扩容。
具体面试时使用
◆ ◆ ◆ ◆
当年掌握到这里就去面试了,阿里的面试官问了小明同学它们三个的差别以及使用场景,然后又问了下面的问题:
String str = "aaa"+"bbb"+"ccc"+“ddd”;
这句代码的生成情况是什么:
小明同学回答:
首先“aaa”和“bbb”,生成“aaabbb”,然后在生成"aaabbbccc",最后是“aaabbbcccddd”;
答案是对的!
接下来问了个至今印象深刻的问题!
循环五万次
String str = "aaa"+"bbb"+"ccc"+“ddd”;
和
StringBuilder str = new StringBuilder(max);
str.append("aaa");
str.append("bbb");
str.append("ccc");
str.append("ddd");
哪个时间更快?
当时小明同学脑中是觉得String会创建很多对象,然后再拼接,肯定是第一个慢!
之后面试官露出一个诡异的笑容……告诉我,第一个时间快,并且速度接近为0!
当时我就震惊了!
这是为什么呢!
看看下面的结果:
这个是在idea里面写的
这个是编译后用反编译软件打开的。
结果就是:
java在编译的时候,对于静态字符串的连接操作,就已经在编译时合成了一个单独的字符串了。
StringBuilder则需要如实调用,所以时间长。
以上就是String的坑!
再补充一点,如果是String的变量的累加,那又是怎么样的呢?
即
String str1 = "aaa";
String str2 = "bbb";
String str3 = "ccc";
String str4 = "ddd";
String str = str1+str2+str3+str4;
这样和StringBuilder的比,哪个更快呢?
结果是:性能差不多!
因为在编译的时候,最后一句会被编译成
String str = (new StringBuilder(String.valueOf(str1))).append(str2).append(str3).append(str4).toString();
就是编译时,就已经做过处理了,这些看起来很慢的代码,实际并不慢。
- end -
祝各位人人都能涨20K!
每个人都是技术大牛!
点击关注,不要走开哟~
- TEN END -