Java中String、StringBuffer、StringBuilder的区别

来源:互联网 发布:红叶知弦调教 编辑:程序博客网 时间:2024/05/18 13:45

1,可变与不可变

首先三者的类都是final修饰的,因此不能被继承。
String类中使用字符数组保存字符串,格式为private final char value[],因为有“final”修饰符,所以可以知道string对象是不可变的。
StringBuilder与StringBuffer都继承自AbstractStringBuilder抽象类,它定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。在AbstractStringBuilder中也是使用字符数组保存字符串,格式为char[] value,可知这两种对象都是可变的。

2,多线程安全

String中的对象是不可变的,也就可以理解为常量,显然线程安全
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。
StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。

3,用法

StringBuilder是JDK5.0新增的,该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。其常用构造方法如下:

  • StringBuilder():创建一个容量为16的StringBuilder对象(16个空元素)
  • StringBuilder(int initCapacity):创建一个容量为initCapacity的StringBuilder对象
  • StringBuilder(String s):创建一个包含s的StringBuilder对象,末尾附加16个空元素

常用方法主要包括insert(),replace(),substring(),delete()甚至reverse(),最常用的还是append()和toString()。

String是不可变的对象, 因此在每次对String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。

使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以字符串对象经常改变的情况下推荐使用 StringBuffer。

总结:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。

4,操作符“+”的重载和StringBuilder

操作符“+”可以连接String,在某些特别情况下, String 对象的字符串拼接其实是被 Java Compiler 编译成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,例如:

String s1 = “This is only a” + “ simple” + “ test”;StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

Java Compiler直接把上述第一条语句编译为:

String s1 = “This is only a simple test”;

但要注意的是,如果拼接的字符串来自另外的String对象的话,Java Compiler就不会自动转换了,速度也就没那么快了,例如:

String s2 = “This is only a”;String s3 = “ simple”;String s4 = “ test”;String s1 = s2 + s3 + s4;

在这个例子中,编译器创建了一个StringBuilder对象,为每个字符串调用一次append()方法,总计三次,然后调用toString()方法生成结果。
所以,不要使用String类的”+”来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。例如:

// 使用操作符“+”String result = "";for (String s : hugeArray) {    result = result + s;}// 使用StringBuilderStringBuilder sb = new StringBuilder();for (String s : hugeArray) {    sb.append(s);}String result = sb.toString();

第一种使用操作符“+”的方法,每一次循环都会创建一个新的StringBuilder对象。而第二种方法只生成一个。显式地创建StringBuilder还允许预先指定大小,可以避免多次重新分配缓冲。

5,String上的常用操作

  1. char charAt(int index):返回指定索引处的 char 值。
  2. int compareTo(String anotherString):按字典顺序比较两个字符串。
  3. String concat(String str):将指定字符串连接到此字符串的结尾。
  4. boolean contentEquals(StringBuffer sb):当且仅当字符串与指定的StringButter有相同顺序的字符时候返回真。
  5. static String copyValueOf(char[] data, int offset, int count):返回指定数组中表示该字符序列的String。
  6. boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束。
  7. boolean equals(Object anObject):将此字符串与指定的对象比较。
  8. void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):将字符从此字符串复制到目标字符数组。
  9. int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
  10. int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
  11. int length():返回此字符串的长度。
  12. boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
  13. boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len):测试两个字符串区域是否相等。
  14. String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar替换此字符串中出现的所有 oldChar 得到的。
  15. String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
  16. String replaceFirst(String regex, String replacement):使用给定的 replacement替换此字符串匹配给定的正则表达式的第一个子字符串。
  17. String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此字符串。
  18. boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
  19. String substring(int beginIndex, int endIndex):返回一个新字符串,它是此字符串的一个子字符串。
  20. char[] toCharArray():将此字符串转换为一个新的字符数组。
  21. String trim():返回字符串的副本,忽略前导空白和尾部空白。

参考自:
http://www.cnblogs.com/xudong-bupt/p/3961159.html
http://blog.csdn.net/kingzone_2008/article/details/9220691

阅读全文
0 0
原创粉丝点击