2、StringBuffer和StringBuilder
StringBuffer就是为了解决大量拼接字符串时产生很多中间对象问题而提供的一个类,提供append和add方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列,把所有修改数据的方法都加上了synchronized。但是保证了线程安全是需要性能的代价的。在很多情况下我们的字符串拼接操作不需要线程安全,这时候StringBuilder登场了,StringBuilder是JDK1.5发布的,它和StringBuffer本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。
StringBuffer 和 StringBuilder 二者都继承了 AbstractStringBuilder ,底层都是利用可修改的char数组(JDK 9 以后是 byte数组)。所以如果我们有大量的字符串拼接,如果能预知大小的话最好在new StringBuffer 或者StringBuilder 的时候设置好capacity,避免多次扩容的开销。扩容要抛弃原有数组,还要进行数组拷贝创建新的数组。
3、为什么String=String
public class Test01 {
public static void main(String[] args){
String str1 = “123”;
String str2 = “123”;
System.out.println(str0 == str1);
}
}
public class Test02 {
public static void main(String[] args){
String str3 = new String(“123”);
String str4 = new String(“123”);
System.out.println(str0 == str1);
}
}
其运行结果 Test01 为true,Test02为false ,这是为什么呢?
“==”方法其实比较的不是两个对象的值,而是比较两个对象的引用是否相等。在JVM中有一块区域叫做常量池,常量池中的数据是那些在编译期间被确定,并被保存在已编译的.class文件中的一些数据。除了包含所有的8种基本数据类型(char、byte、short、int、long、float、double、boolean)外,还有String及其数组的常量值,另外还有一些以文本形式出现的符号引用。
Java栈的特点是存取速度快(比堆块),但是空间小,数据生命周期固定,只能生存到方法结束。栈有一个特点就是数据共享。
当我们创建str1的时候,编译的时候会在常量池中创建一个常亮“123”,当我们去创建str2时,它会先去常量池中寻找是否有一个常亮是“123”,如果有,那么str2指向的就是这个“123”,所以Test01的结果为true。(注:先看常量池中有没有要创建的数据,有就返回数据的地址,没有就创建一个。)
最后总结
搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析
最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化
(学习笔记):分布式+微服务+开源框架+性能优化**
[外链图片转存中…(img-QxGdgtDa-1719176441942)]