【Java】——String、StringBuilder与StringBuffer的区别

版权声明:未经过博主同意,不得随意转发 https://blog.csdn.net/weixin_40918067/article/details/82257022

String类是不可变类,任何对String的改变都会引发新的String对象的生成;

StringBuffer是可变类,任何对它所指代的字符串的改变都不会产生新的对象,可变和不可变类这一对对象已经齐全了;

引入新的StringBuilder类???——》改变字符串内容时,采用StringBuffer能获得更好的性能,但是并不是最好的;

StringBuffer???——》线程安全

StringBuilder???——》非线程安全

【例子】String类为不可变类;

解析:

  • 初始String值为“hello”,之后在这个字符串后面加上新的字符串“world”;
  • 这个过程是需要重新在栈堆内存中开辟内存空间,才最终得到了“hello world”字符串,但同时也相应的需要开辟内存空间;
  • 这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费;
  • 为了应对经常性的字符串相关的操作,谷歌引入了两个新的类——StringBuffer类和StringBuilder类来对此中变化字符串进行处理;

那StringBuilder和StringBuffer的区别:

  • HashTable是线程安全的,很多方法都是synchronized方法;
  • HashMap不是线程安全的,但其在单线程程序中的性能比HashTable要高;
  • StringBuffer和StringBuilder类的区别也在于此???——》就是支持线程同步保证线程安全而导致性能下降的问题;???——》StringBuilder类不是线程安全的,但其在单线程中的性能比StringBuffer高;
  • 在大多数情况下建议使用StringBuilder类;但是在应用程序要求线程安全的情况下,则必须使用StringBuffer类;

三者的继承关系:

扫描二维码关注公众号,回复: 3090797 查看本文章

那么,接下来就用实例来证明:

package com.hct.test;
 
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
 
/**
 * @author: chengtai.he
 * @created:2009-12-9 上午09:59:57
 */
public class StringBuilderTester {
 private static final String base = " base string. ";
 private static final int count = 2000000;
 
 public static void stringTest() {
  long begin, end;
  begin = System.currentTimeMillis();
  String test = new String(base);
  for (int i = 0; i < count/100; i++) {
   test = test + " add ";
  }
  end = System.currentTimeMillis();
  System.out.println((end - begin)
    + " millis has elapsed when used String. ");
 }
 
 public static void stringBufferTest() {
  long begin, end;
  begin = System.currentTimeMillis();
  StringBuffer test = new StringBuffer(base);
  for (int i = 0; i < count; i++) {
   test = test.append(" add ");
  }
  end = System.currentTimeMillis();
  System.out.println((end - begin)
    + " millis has elapsed when used StringBuffer. ");
 }
 
 public static void stringBuilderTest() {
  long begin, end;
  begin = System.currentTimeMillis();
  StringBuilder test = new StringBuilder(base);
  for (int i = 0; i < count; i++) {
   test = test.append(" add ");
  }
  end = System.currentTimeMillis();
  System.out.println((end - begin)
    + " millis has elapsed when used StringBuilder. ");
 }
 
 public static String appendItemsToStringBuiler(List list) {
  StringBuilder b = new StringBuilder();
 
  for (Iterator i = list.iterator(); i.hasNext();) {
   b.append(i.next()).append(" ");
  }
 
  return b.toString();
 }
 
 public static void addToStringBuilder() {
  List list = new ArrayList();
  list.add(" I ");
  list.add(" play ");
  list.add(" Bourgeois ");
  list.add(" guitars ");
  list.add(" and ");
  list.add(" Huber ");
  list.add(" banjos ");
 
  System.out.println(StringBuilderTester.appendItemsToStirngBuffer(list));
 }
 
 public static String appendItemsToStirngBuffer(List list) {
  StringBuffer b = new StringBuffer();
 
  for (Iterator i = list.iterator(); i.hasNext();) {
   b.append(i.next()).append(" ");
  }
 
  return b.toString();
 }
 
 public static void addToStringBuffer() {
  List list = new ArrayList();
  list.add(" I ");
  list.add(" play ");
  list.add(" Bourgeois ");
  list.add(" guitars ");
  list.add(" and ");
  list.add(" Huber ");
  list.add(" banjos ");
 
  System.out.println(StringBuilderTester.appendItemsToStirngBuffer(list));
 }
 
 public static void main(String[] args) {
  stringTest();
  stringBufferTest();
  stringBuilderTest();
  addToStringBuffer();
  addToStringBuilder();
 }
}

上面的程序结果如下:

5266 millis has elapsed when used String. 
375 millis has elapsed when used StringBuffer. 
281 millis has elapsed when used StringBuilder. 
 I   play   Bourgeois   guitars   and   Huber   banjos  
 I   play   Bourgeois   guitars   and   Huber   banjos 

解析:

  1. 从上面的结果来看,这三个类在单线程程序中的性能差别一目了然;
  2. 采用String对象时,即使运行次数仅是采用其他对象的1/100,但其执行时间仍然比其他对象高出25倍以上;
  3. 而采用StringBuffer对象和采用StringBuilder对象的差别也比较明显,前者是后者的1.5倍左右;
  4. 由此可见,如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;
  5. 当然,如果要保证线程安全,自然非StringBuffer莫属了;
  • 除了对多线程的支持不一样外,这两个类的使用几乎没有任何差别,上面的例子就是个很好的说明;
  • appendItemsToStringBuiler和appendItemsToStirngBuffer两个方法除了采用的对象分别为StringBuilder和StringBuffer外,其他完全相同,而且效果也完全相同;

小结:

  1. 如果要操作少量的数据用 String;
  2. 多线程操作字符串缓冲区下操作大量数据 StringBuffer;
  3. 单线程操作字符串缓冲区下操作大量数据 StringBuilder;

 

大家给个赞,就是给我最大的鼓励!!!

注意:“赞”位于右上角;

猜你喜欢

转载自blog.csdn.net/weixin_40918067/article/details/82257022