文章目录
StringBuffer类
- String类有一条特性就是内容一旦声明则不可改变,内容相同的两个字符串会在同一个内存中,地址相同。如果要改变,则改变的肯定是String的引用地址,通过加法拼接字符串,尽量是能避免就避免,会产生大量的内存垃圾,因为每拼接一次就会产生一个无引用的内存地址。它是在字符串的常量池中缓存着的,哪怕你不用,它也不会被GC。
- 如果必须进行字符串的拼接,建议使用StringBuilder和StringBuffer,这种方法更节省内存。
1. append()方法连接各种类型的数据
- 代码示例
public class Test01 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("hello\t");
sb.append("java").append("!!");
sb.append("\n数字:").append(1);
sb.append("\n字符:").append('A');
sb.append("\n布尔:").append(true);
System.out.println(sb);
}
}
- 运行结果
hello java!!
数字:1
字符:A
布尔:true
2. insert()方法在任意位置处为StringBuffer添加内容
- 代码示例
public class Test02 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("java").append("!!");
// 在所有内容之前添加
sb.insert(0,"hello\t");
System.out.println(sb);
// 在所有内容之后添加
sb.insert(sb.length(),"牛逼!");
System.out.println(sb);
}
}
- 运行结果
hello java!!
hello java!!牛逼!
3. reverse()方法实现字符串反转
- 代码示例
public class Test03 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("java").append("!!");
sb.reverse();
System.out.println(sb);
}
}
- 运行结果
!!avaj
4. replace()方法替换指定范围的内容
- 代码示例
public class Test04 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("java").append("!!");
// 将“!!”替换为“很好用的一门语言”
sb.replace(4,6,"很好用的一门语言");
System.out.println(sb);
}
}
- 运行结果
java很好用的一门语言
5. substring()方法实现字符串截取
- 代码示例
public class Test05 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("java").append("!!");
// 指定截取范围,并把内容转换为String类型
String str = sb.substring(0,4);
System.out.println(str);
}
}
- 运行结果
java
6. delete()方法删除指定范围的字符串
- 代码示例
public class Test06 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("hello ");
sb.append("java").append("!!");
// 删除指定范围字符串
sb.delete(10,12);
System.out.println(sb);
}
}
- 运行结果
hello java
7. indexOf()方法查找指定的内容是否存在
- 代码示例
public class Test07 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("hello ").append("java");
// indexOf查找指定字符串,未查到则返回-1
if (sb.indexOf("java") == -1) {
System.out.println("未找到指定的内容!");
} else {
System.out.println("已找到指定内容!");
}
}
}
- 运行结果
已找到指定内容!
StringBuilder类
从JDK1.5开始,java增加了一个新的字符串操作类StringBuilder类。
- 区别:
StringBuffer类的定义结构:
public final class StringBuffer extends Object implements Serializable, Comparable<StringBuffer>, CharSequence
StringBuider类的定义结构:
public final class StringBuilder extends Object implements Serializable, Comparable<StringBuilder>, CharSequence
通过定义结构可以发现,StringBuffer类与StringBuilder类是完全相同的,而且查阅Java Doc文档发现两个类定义的方法功能也是相同的。
但是分析源码就会发现区别:
- 部分源码对比:
@Override
public synchronized StringBuffer reverse() {
toStringCache = null;
super.reverse();
return this;
}
@Override
@HotSpotIntrinsicCandidate
public synchronized String toString() {
if (toStringCache == null) {
return toStringCache =
isLatin1() ? StringLatin1.newString(value, 0, count)
: StringUTF16.newString(value, 0, count);
}
return new String(toStringCache);
}
...
@Override
public StringBuilder reverse() {
super.reverse();
return this;
}
@Override
@HotSpotIntrinsicCandidate
public String toString() {
// Create a copy, don't share the array
return isLatin1() ? StringLatin1.newString(value, 0, count)
: StringUTF16.newString(value, 0, count);
}
...
在StringBuffer类中定义的方法全部使用synchronized进行同步定义,而StringBuilder类中没有,所以StringBuilder类的方法都是异步方法。
- 所以:
StringBuilder是线程不安全的实现
StringBuffer是线程安全的实现
常见面试题分析:
请解释String、StringBuffer、StringBuilder的区别。
-
String的内容一旦声明则不可改变,而StringBuffer与StringBuilder声明的内容可以改变。
-
StringBuffer类中提供的方法都是同步方法,属于安全的线程操作,而StringBuilder类中的方法都属于异步方法,属于非线程安全的操作。