相信大家看到过很多比较String和StringBuffer区别的文章,也明白这两者的区别,然而自从Java 5.0发布以后,我们的比较列表上将多出一个对象了,这就是StringBuilder类。String类是不可变类,任何对String的改变都会引发新的String对象的生成;而StringBuffer则是可变类,任何对它所指代的字符串的改变都不会产生新的对象,可变和不可变类这一对对象已经齐全了,那么为什么还要引入新的StringBuilder类干吗?相信大家都有此疑问,我也如此。下面,我们就来看看引入该类的原因。

为什么会出现那么多比较String和StringBuffer的文章?

原因在于当改变字符串内容时,采用StringBuffer能获得更好的性能。既然是为了获得更好的性能,那么采用StringBuffer能够获得最好的性能吗?

答案是NO!

为什么?

如果你读过《Think in Java》,而且对里面描述HashTable和HashMap区别的那部分章节比较熟悉的话,你一定也明白了原因所在。对,就是支持线程同步保证线程安全而导致性能下降的问题。HashTable是线程安全的,很多方法都是synchronized方法,而HashMap不是线程安全的,但其在单线程程序中的性能比HashTable要高。StringBuffer和StringBuilder类的区别也在于此,新引入的StringBuilder类不是线程安全的,但其在单线程中的性能比StringBuffer高。如果你对此不太相信,可以试试下面的例子:

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 
从上面的结果来看,这三个类在单线程程序中的性能差别一目了然,采用String对象时,即使运行次数仅是采用其他对象的1/100,其执行时间仍然比其他对象高出25倍以上;而采用StringBuffer对象和采用StringBuilder对象的差别也比较明显,前者是后者的1.5倍左右。由此可见,如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;当然,如果要保证线程安全,自然非StringBuffer莫属了。

除了对多线程的支持不一样外,这两个类的使用几乎没有任何差别,上面的例子就是个很好的说明。appendItemsToStringBuiler和appendItemsToStirngBuffer两个方法除了采用的对象分别为StringBuilder和StringBuffer外,其他完全相同,而效果也完全相同。

还有一个知乎上比较好的介绍:https://www.zhihu.com/question/20101840

String Buffer和String Builder的区别(转)的更多相关文章

  1. String、String Buffer、String Builder

    对于String.String Buffer.String Builder:我一直都只知道String是字符串常量,后两者是字符串变量: String和String Buffer是线程安全的,Stri ...

  2. String Buffer和String Builder(String类深入理解)

      String在Java里面JDK1.8后它属于一个特殊的类,在创建一个String基本对象的时候,String会向“ 字符串常量池(String constant pool)” 进行检索是否有该数 ...

  3. String String Buffer String Builder

    如题,在java中这是一个典型的问题. 在stackoverflow上已经有很多相似的问题被提问,并且有很多不正确或不完整的答案.如果你不往深处想,这是一个很简单的问题.但如果深入思考,它却很让人迷惑 ...

  4. String详解, String和CharSequence区别, StringBuilder和StringBuffer的区别 (String系列之1)

    本章主要介绍String和CharSequence的区别,以及它们的API详细使用方法. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/string01. ...

  5. [drp 2]String、StringBuffer和StringBuilder的区别

    导读:在实际运用了,我们会频繁的用到string.stringBuffer和stringBuilder这三个东西,那么,他们之间的区别是什么呢.本文主要是从拼写SQL语句的角度,来阐释他们之间的区别! ...

  6. 【转载】String、StringBuffer与StringBuilder之间区别

    文章来源:http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 这两天在看Java编程的书,看到String的时候将之前没有弄懂的 ...

  7. String详解, String和CharSequence区别, StringBuilder和StringBuffer的区别

    本章主要介绍String和CharSequence的区别,以及它们的API详细使用方法. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/string01. ...

  8. String、StringBuffer与StringBuilder的区别。

    无论是做Java或是Android,都避免不了遇到这个问题,其实开发过程中一般情况下是不会纠结,这个问题是面试必选经典题,今天有时间,就总结一下. String.StringBuffer.String ...

  9. String、StringBuffer与StringBuilder之间区别[全屏看文]

    String.StringBuffer与StringBuilder之间区别[全屏看文]   最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,S ...

随机推荐

  1. Linux系统的关机、重启、睡眠

    一.关机.重启前的准备1.查看网络联机状态.后台可执行程序 查看一下两样东西,可以让你稍微了解主机目前的使用状态 查看网络联机状态:netstat  -a查看后台执行的程序:ps  -aux2.数据同 ...

  2. Laya发布微信小游戏项目

    版本2.1.1.1 创建项目时,勾选微信/百度小游戏bin目录快速调试 发布项目时,选择发布平台为微信小游戏 用微信开发者工具打开release/wxgame,这就是微信小游戏项目了,很方便

  3. ABAP函数篇2 测试DATE_CONVERT_TO_FACTORYDATE

    DATE_CONVERT_TO_FACTORYDATE   根据日期返回工厂日历日期 函数功能说明: 标出工作日的计算方法 输入传输 CORRECT_OPTION = '+'如果指定的日期不是工作日, ...

  4. 编译安装hls协议切片工具 m3u8-segmenter

    操作系统:Ubuntu16.04.4 amd64 安装http://m3u8-segmenter.inodes.org/方式安装m3u8-segmenter报错,于是有了这篇文章 apt instal ...

  5. [ kvm ] 学习笔记 1:Linux 操作系统及虚拟化

    1. 前言 一台计算机是由一堆硬件设备组合而成,在硬件之上是操作系统,操作系统与计算机硬件密不可分,操作系统用来管理所有的硬件资源提供服务,各个硬件设备是通过 总线 进行连接起来的: 在操作系统之上, ...

  6. CSS3 column 分栏

     column的布局形式还没有使用过,后续的bug和解决方案有待检验. column column-count:number: 设置内容分为多少栏显示 column-width:长度单位:设置每一栏的 ...

  7. python解析本地HTML文件

    Python使用爬虫技术时,每运行一次,本地都会访问一次主机.为避免完成程序前调试时多次访问主机增加主机负荷,我们可以在编写程序前将网页源代码存在本地,调试时访问本地文件即可.现在我来分享一下爬取资料 ...

  8. 老司机带大家领略MySQL中的乐观锁和悲观锁

    原文地址:https://cloud.tencent.com/developer/news/227982 为什么需要锁 在并发环境下,如果多个客户端访问同一条数据,此时就会产生数据不一致的问题,如何解 ...

  9. Hive 企业调优

    9.企业级调优 9.1 Fetch 抓取 Fetch 抓取:Hive 中对某些情况的查询可以不必使用 MapReduce 计算: hive.fetch.task.conversion:more 9.2 ...

  10. ASP.NET请求过程-视图如何返回客户端

    本文主要讲控制器返回ActionResult后怎么变成html到客户端的. 控制器返回的各种类型 返回所有类型的基类ActionResult // // 摘要: // 表示操作方法的结果. publi ...