💨💨💨—— 前言
- 我们在实际开发的时候,如果需要进行字符串的频繁拼接,会占用大量的方法区(字符串常量池)内存,造成内存空间的浪费。
——因为Java中的字符串是不可变的,每一次拼接都会产生新的字符串
例:
- String s = “abc”;
- s += “hello”;
以上两行代码,就导致方法区字符串常量池当中创建了三个对象
“abc”、“hello”、“abchello”- 如果以后需要进行大量字符串的拼接操作,为了解决频繁拼接造成的内存空间浪费问题,建议使用JDK自带的:
- java.lang.StringBuffer
- java.lang.StringBuilder
💨💨💨—— StringBuffer
- 构造方法
StringBuffer()
构造一个没有字符的字符串缓冲区,初始容量为16个字符。
StringBuffer(CharSequence seq)
构造一个包含与指定的相同字符的字符串缓冲区 CharSequence 。
StringBuffer(int capacity)
构造一个没有字符的字符串缓冲区和指定的初始容量。
StringBuffer(String str)
构造一个初始化为指定字符串内容的字符串缓冲区。 - 主要方法
append() : 将给定的数据转换为字符串,然后将该字符串的字符附加到字符串缓冲区末尾
insert() : 将给定的数据转换为字符串,然后将该字符串的字符插入到字符串缓冲区指定的下标位置
注:
1. 每个字符串缓冲区都有一个容量。 只要字符串缓冲区中包含的字符序列的长度不超过容量,就不必分配新的内部缓冲区数组。 如果内部缓冲区溢出,则会自动变大。
2. sb.append(x) 和 sb.insert(sb.length(), x) 具有相同的效果
public class StringBuffer01 { public static void main(String[] args) { // 创建一个字符串缓冲区对象,无参构造默认初始化容量为16的char[]数组 StringBuffer stringBuffer = new StringBuffer(); // 创建一个字符串缓冲区对象,传入一个int参数指定初始化容量的char[]数组 StringBuffer sb = new StringBuffer(100);//初始化容量为100 // 以后拼接字符串统一调用append()方法 // append是追加的意思 // append方法底层在进行追加的时候,如果char[]数组满了,会自动扩容。 stringBuffer.append("a"); stringBuffer.append("c"); stringBuffer.append("d"); stringBuffer.append("e"); // 如果追加的字符串对象引用指向为空,则追加"n" "u" "l" "l" String s = null; stringBuffer.append(s); // insert是插入的意思 // insert方法底层在进行插入的时候,如果char[]数组满了,会自动扩容。 stringBuffer.insert(1, "b"); System.out.println(stringBuffer); } }
- 如何优化StringBuffer的性能
- 在创建StringBuffer的时候尽可能给定一个初始化容量
- 最好减少底层数组的扩容次数。预估计一下,给一个大一些初始化容量。
关键点:给一个合适的初始化容量。可以提高程序的执行效率。
💨💨💨—— StringBuilder
- 使用StringBuilder也是可以完成字符串的拼接,其功能跟StringBuffer一样
- StringBuilder和StringBuffer的区别:
- StringBuffer中的方法都有 synchronized 关键字修饰。表示StringBuffer在多线程环境下运行是安全的。
StringBuilder中的方法都没有 synchronized 关键字修饰,表示StringBuilder在多线程环境下运行是不安全的。- StringBuffer是线程安全的。
StringBuilder是非线程安全的。
💨💨💨—— String和StringBuffer(StringBuilder)区别
- String创建后为什么是不可变的?
------源代码中,String类中有一个被final修饰的char[]数组,因为数组一旦创建长度不可变,并且被final修饰的引用一旦指向某个对象之后,不可再指向其他对象,所以String是不可变的!例:字符串常量池中的"abc"无法直接变成"abcd"
- StringBuilder/StringBuffer为什么是可变的呢?
------源代码中,StringBuffer/StringBuilder内部实际上是一个char[]数组,且该数组没有被final修饰;StringBuffer/StringBuilder的初始化容量为16,当存满之后会进行扩容,底层调用了数组拷贝System.arraycopy()方法扩容,所以StringBuilder/StringBuffer适合于使用字符串的频繁拼接操作