常用方法
1、insert
privatestaticvoidtestInsertAPIs(){
System.out.println("---------- testInsertAPIs -----------");
StringBuildersbuilder=newStringBuilder();
// 在位置0处插入字符数组
sbuilder.insert(0, newchar[]{'a', 'b', 'c', 'd', 'e'}); // abcde
// 在位置0处插入字符数组。0表示字符数组起始位置,3表示长度
sbuilder.insert(0, newchar[]{'A', 'B', 'C', 'D', 'E'}, 0, 3); // ABCabcde
// 在位置0处插入float
sbuilder.insert(0, 1.414f); // 1.414ABCabcde
// 在位置0处插入double
sbuilder.insert(0, 3.14159d);
// 在位置0处插入boolean
sbuilder.insert(0, true);
// 在位置0处插入char
sbuilder.insert(0, '\n');
// 在位置0处插入int
sbuilder.insert(0, 100);
// 在位置0处插入long
sbuilder.insert(0, 12345L);
// 在位置0处插入StringBuilder对象
sbuilder.insert(0, newStringBuilder("StringBuilder"));
// 在位置0处插入StringBuilder对象。6表示被在位置0处插入对象的起始位置(包括),13是结束位置(不包括)
sbuilder.insert(0, newStringBuilder("STRINGBUILDER"), 6, 13);
// 在位置0处插入StringBuffer对象。
sbuilder.insert(0, newStringBuffer("StringBuffer"));
// 在位置0处插入StringBuffer对象。6表示被在位置0处插入对象的起始位置(包括),12是结束位置(不包括)
sbuilder.insert(0, newStringBuffer("STRINGBUFFER"), 6, 12);
// 在位置0处插入String对象。
sbuilder.insert(0, "String");
// 在位置0处插入String对象。1表示被在位置0处插入对象的起始位置(包括),6是结束位置(不包括)
sbuilder.insert(0, "0123456789", 1, 6);
sbuilder.insert(0, '\n');
// 在位置0处插入Object对象。此处以HashMap为例
HashMapmap=newHashMap();
map.put("1", "one");
map.put("2", "two");
map.put("3", "three");
sbuilder.insert(0, map);
System.out.printf("%s\n\n", sbuilder);
}
2、append
/**
* StringBuilder 的append()示例
*/
privatestaticvoidtestAppendAPIs() {
System.out.println("------------------- testAppendAPIs -----------------
--");
StringBuildersbuilder=newStringBuilder();
// 追加字符数组
sbuilder.append(newchar[]{'a','b','c','d','e'});
// 追加字符数组。0表示字符数组起始位置,3表示长度
sbuilder.append(newchar[]{'A','B','C','D','E'}, 0, 3);
// 追加float
sbuilder.append(1.414f);
// 追加double
sbuilder.append(3.14159d);
// 追加boolean
sbuilder.append(true);
// 追加char
sbuilder.append('\n');
// 追加int
sbuilder.append(100);
// 追加long
sbuilder.append(12345L);
// 追加StringBuilder对象
sbuilder.append(newStringBuilder("StringBuilder"));
// 追加StringBuilder对象。6表示被追加对象的起始位置(包括),13是结束位置(不包括)
sbuilder.append(newStringBuilder("STRINGBUILDER"), 6, 13);
// 追加StringBuffer对象。
sbuilder.append(newStringBuffer("StringBuffer"));
// 追加StringBuffer对象。6表示被追加对象的起始位置(包括),12是结束位置(不包括)
sbuilder.append(newStringBuffer("STRINGBUFFER"), 6, 12);
// 追加String对象。
sbuilder.append("String");
// 追加String对象。1表示被追加对象的起始位置(包括),6是结束位置(不包括)
sbuilder.append("0123456789", 1, 6);
sbuilder.append('\n');
// 追加Object对象。此处以HashMap为例
HashMapmap=newHashMap();
map.put("1", "one");
map.put("2", "two");
map.put("3", "three");
sbuilder.append(map);
sbuilder.append('\n');
// 追加unicode编码
sbuilder.appendCodePoint(0x5b57); // 0x5b57是“字”的unicode编码
sbuilder.appendCodePoint(0x7b26); // 0x7b26是“符”的unicode编码
sbuilder.appendCodePoint(0x7f16); // 0x7f16是“编”的unicode编码
sbuilder.appendCodePoint(0x7801); // 0x7801是“码”的unicode编码
System.out.printf("%s\n\n", sbuilder);
}
3、replace
reverse():反转
replace(start,end,str):从[start,end)替换str
setCharAt(n, ch):在位置n上设置字符ch
/**
* StringBuilder 的replace()示例
*/
privatestaticvoidtestReplaceAPIs() {
System.out.println("------------------- testReplaceAPIs-------------------");
StringBuildersbuilder;
sbuilder=newStringBuilder("0123456789");
sbuilder.replace(0, 3, "ABCDE"); // [0,3)
System.out.printf("sbuilder=%s\n", sbuilder);// sbuilder=ABCDE3456789
sbuilder=newStringBuilder("0123456789");
sbuilder.reverse();
System.out.printf("sbuilder=%s\n", sbuilder);// 9876543210
sbuilder=newStringBuilder("0123456789");
sbuilder.setCharAt(0, 'M');
System.out.printf("sbuilder=%s\n", sbuilder);// M123456789
System.out.println();
}
4、delete
- deleteCharAt(n):删除位置n上的字符
- delete(start,end):删除字符[start,end)
- substring(n):获取从位置n开始的字符串
- substring(start,end):获取从[start,end)的字符串
- subSequence(start,end):获取从[start,end)的字符串(CharSequence对象)
privatestaticvoidtestDeleteAPIs() {
System.out.println("------------------- testDeleteAPIs -------------------");
StringBuildersbuilder=newStringBuilder("0123456789");
// 删除位置0的字符,剩余字符是“123456789”。
sbuilder.deleteCharAt(0);
// 删除位置3(包括)到位置6(不包括)之间的字符,剩余字符是“123789”。
sbuilder.delete(3,6);
// 获取sb中从位置1开始的字符串
Stringstr1=sbuilder.substring(1);
// 获取sb中从位置3(包括)到位置5(不包括)之间的字符串
Stringstr2=sbuilder.substring(3, 5);
// 获取sb中从位置3(包括)到位置5(不包括)之间的字符串,获取的对象是CharSequence对象,此处转型为String
Stringstr3= (String)sbuilder.subSequence(3, 5);
System.out.printf("sbuilder=%s\nstr1=%s\nstr2=%s\nstr3=%s\n",
sbuilder, str1, str2, str3);
}
5、index
indexof(str):找到字符串str第一次出现的下标
indexof(str,n):找到字符串str第一次出现的下标,从n开始
lastIndexof(str):从后往前,找到字符串str第一次出现的下标
lastIndexof(str,n):从后往前,找到字符串str第一次出现的下标,从n开始
/**
* StringBuilder 中index相关API演示
*/
privatestaticvoidtestIndexAPIs() {
System.out.println("-------------------------------- testIndexAPIs --------------------------------");
StringBuildersbuilder=newStringBuilder("abcAbcABCabCaBcAbCaBCabc");
System.out.printf("sbuilder=%s\n", sbuilder);
// 1. 从前往后,找出"bc"第一次出现的位置 1
System.out.printf("%-30s = %d\n", "sbuilder.indexOf(\"bc\")",
sbuilder.indexOf("bc"));
// 2. 从位置5开始,从前往后,找出"bc"第一次出现的位置 22
System.out.printf("%-30s = %d\n", "sbuilder.indexOf(\"bc\", 5)",
sbuilder.indexOf("bc", 5));
// 3. 从后往前,找出"bc"第一次出现的位置 22
System.out.printf("%-30s = %d\n", "sbuilder.lastIndexOf(\"bc\")",
sbuilder.lastIndexOf("bc"));
// 4. 从位置4开始,从后往前,找出"bc"第一次出现的位置 4
System.out.printf("%-30s = %d\n", "sbuilder.lastIndexOf(\"bc\", 4)",
sbuilder.lastIndexOf("bc", 4));
System.out.println();
}
6、其他API
/**
* StringBuilder 的其它API示例
*/
privatestaticvoidtestOtherAPIs() {
System.out.println("----------- testOtherAPIs -----------");
StringBuildersbuilder=newStringBuilder("0123456789");
intcap=sbuilder.capacity();
System.out.printf("cap=%d\n", cap);
/*
capacity()返回的是字符串缓冲区的容量
StringBuffer( ); 分配16个字符的缓冲区
StringBuffer( int len ); 分配len个字符的缓冲区
StringBuffer( String s ); 除了按照s的大小分配空间外,再分配16个 字符的缓冲区
你的StringBuffer是用字符构造的,"0123456789"的长度是10另外再分配16个字符,所
以一共是26。
*/
charc=sbuilder.charAt(6);
System.out.printf("c=%c\n", c);
char[] carr=newchar[4];
sbuilder.getChars(3, 7, carr, 0); // 将[3,7)的值,依次从下标0的位置上开始赋值
for (inti=0; i<carr.length; i++){
System.out.printf("carr[%d]=%c ", i, carr[i]);
}
System.out.println();
}
3、小结
- String:字符串常量
- StringBuffer:字符串变量(线程安全)
- StringBuilder:字符串变量(非线程安全)
- 执行速度方面:StringBuilder > StringBuffer > String
区别
- String和StringBuffer类型的主要区别在于String是不可变的对象
- 每次在对String更改之后其实等同于生成了一个新的String对象,然后再将指针指向新生成的String对象
- 所以经常改变内容的字符串最好不要用String对象,因为每次生成对象都会对系统的性能产生影响,特别是内存中无引用对象变多了之后,JVM的GC垃圾回收器就会开始工作
- 而StringBuffer类操作时就只是对其本身进行操作,而不是生成新的对象。经常改动字符串内容的时候推荐使用StringBuffer对象
特殊情况:
StringS1=“Thisisonlya”+“simple”+“test”;
StringBufferSb=newStringBuilder(“Thisisonlya”).append(“
simple”).append(“test”);
/*
这里是因为JVM把S1看作This is only a simple test
如果拼接的字符串是来自其他的String对象,速度就没那么快了
*/
使用场景
- 操作少量的数据用String
- 单线程操作字符串缓冲区下操作大量数据(需要经常修改)用StringBuilder
- 多线程操作字符串缓冲区下操作大量数据(需要经常修改)用StringBuffer
- StringBuilder提供与StringBuffer相同的API,通常被用做StringBuffer的简易替换(一般情况下都是单线程且StringBuilder的运行速度更快)
面试题
StringBuilder与StringBuffer的区别,StringBuilder和String的区别
- StringBuilder的效率更高,线程不安全,StringBuilder线程安全,效率低
- String是不可变的,StringBuilder是可变的
- 如果只是简单使用,不需要对字符串进行频繁修改可以用String,反之就需要用StringBuilder(String会产生多余的字符串,占用内存空间)