Java中有多个字符串类,其中最常用的是String类。
由于String类不可变,这在某些场合下可能会造成资源浪费,例如拼接字符串会产生很多无用的中间对象。所以有了两个可变的字符串类StringBuffer和StringBuilder,用于解决相关问题。
1. String类
String类是Java中使用频率最高的类,是一个字符串类。
String对象是不可变对象,加减操作性能较差。
String类的常用方法
String类有一些比较重要的常用方法,如charAt(),concat(),contains(),endsWith(),equals(),equalsIgnoreCase(),hashCode(),indexOf(),length(),matches(),replace(),replaceAll,split(),startsWith(),substring(),trim(),valueOf()。
下面是这些常方法的示例代码和输出结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package MyString;
public class StringTest {
public static void main(String[] args) { String a = "123;456;789;123 "; System.out.println(a.charAt(0)); System.out.println(a.indexOf(";")); System.out.println(a.concat(";000")); System.out.println(a.contains("000")); System.out.println(a.endsWith("000")); System.out.println(a.equals("000")); System.out.println(a.equalsIgnoreCase("000")); System.out.println(a.length()); System.out.println(a.trim()); String[] b = a.split(";"); for (int i = 0; i < b.length; i++) { System.out.println(b[i]); }
System.out.println("===================");
System.out.println(a.substring(2, 5)); System.out.println(a.replace("1", "a")); System.out.println(a.replaceAll("1", "a"));
System.out.println("===================");
String s1 = "12345?6789"; String s2 = s1.replace("?", "a"); String s3 = s1.replaceAll("[?]", "a"); System.out.println(s2); System.out.println(s3); System.out.println(s1.replaceAll("[\\d]", "a"));
} }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 1 3 123;456;789;123 ;000 false false false false 16 123;456;789;123 123 456 789 123 =================== 3;4 a23;456;789;a23 a23;456;789;a23 =================== 12345a6789 12345a6789 aaaaa?aaaa
|
2. StringBuffer/StringBuilder
StringBuffer/StringBuilder都是可变字符串。
StringBuffer/StringBuilder中的方法一样,区别在于同步。
- StringBuffer:字符串加减,同步,性能好。
- StringBuilder:字符串加减,不同步,性能更好。
-
StringBuffer/StringBuilder的常用方法有
append(),insert(),delete(),replace(),substring(),
toString() 转换为String类型,
length() 字符串实际大小(长度),
capacity() 字符串占用空间大小,
trimToSize() 去除空隙,将字符串存储压缩到实际大小。
如果有大量 append(),事先预估大小,再调用相应的构造函数,性能会更好一些。
-
下面是关于StringBuffer/StringBuilder,字符串长度与占用空间的测试,以StringBuffer为例。
StringBuffer的的初始大小为(16+初始字符串长度)即capacity=16+初始字符串长度。
append()操作后,一旦length大于capacity时,capacity便在前一次的基础上加1后翻倍。
如果append()的对象很长,超过(加1再2倍数额),将以最新的长度更换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| package MyString;
public class StringBufferCapacityTest {
public static void main(String[] args) { StringBuffer sb1 = new StringBuffer(); System.out.println("sb1 length: " + sb1.length()); System.out.println("sb1 capacity: " + sb1.capacity()); System.out.println("=====================");
StringBuffer sb2 = new StringBuffer("123"); sb2.append("456"); System.out.println("sb2 length: " + sb2.length()); System.out.println("sb2 capacity: " + sb2.capacity()); System.out.println("=====================");
sb2.append("7890123456789"); System.out.println("sb2 length: " + sb2.length()); System.out.println("sb2 capacity: " + sb2.capacity()); System.out.println("=====================");
sb2.append("0"); System.out.println("sb2 length: " + sb2.length()); System.out.println("sb2 capacity: " + sb2.capacity()); System.out.println("=====================");
sb2.append("1234567890123456789012345678901234567890123456789012345678901234567890"); System.out.println("sb2 length: " + sb2.length()); System.out.println("sb2 capacity: " + sb2.capacity());
System.out.println("====================="); sb2.append("0"); System.out.println("sb2 length: " + sb2.length()); System.out.println("sb2 capacity: " + sb2.capacity()); sb2.trimToSize(); System.out.println("=====after trime================"); System.out.println("sb2 length: " + sb2.length()); System.out.println("sb2 capacity: " + sb2.capacity()); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| sb1 length: 0 sb1 capacity: 16 ===================== sb2 length: 6 sb2 capacity: 19 ===================== sb2 length: 19 sb2 capacity: 19 ===================== sb2 length: 20 sb2 capacity: 40 ===================== sb2 length: 90 sb2 capacity: 90 ===================== sb2 length: 91 sb2 capacity: 182 =====after trime================ sb2 length: 91 sb2 capacity: 91
|
3. 三种字符串类拼接性能比较
在下面的代码中,分别使用对String类,StringBuffer类,StringBuilder类进行50000次拼接操作,
耗时分别为1194,6和3。很明显,在拼接字符串效率上,StringBuffer/StringBuilder要远远好于String,StringBuilder又略好于StringBuffer。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package MyString;
import java.util.Calendar;
public class StringAppendTest {
public static void main(String[] args) { int n = 50000; Calendar t1 = Calendar.getInstance(); String a = new String(); for(int i=0;i<n;i++) { a = a + i + ","; } System.out.println(Calendar.getInstance().getTimeInMillis() - t1.getTimeInMillis());
Calendar t2 = Calendar.getInstance(); StringBuffer b = new StringBuffer(""); for(int i=0;i<n;i++) { b.append(i); b.append(","); } System.out.println(Calendar.getInstance().getTimeInMillis() - t2.getTimeInMillis());
Calendar t3 = Calendar.getInstance(); StringBuilder c = new StringBuilder(""); for(int i=0;i<n;i++) { b.append(i); b.append(","); } System.out.println(Calendar.getInstance().getTimeInMillis() - t3.getTimeInMillis()); } }
|