`

尽量使用StringBuilder和StringBuffer进行字符串连接

    博客分类:
  • J2EE
阅读更多
相信大家看到过很多比较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要高。单线程应尽量使用HashMap、ArrayList、HashTable、Vector等使用了同步机制,降低了性能。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外,其他完全相同,而效果也完全相同。


尽量确定StringBuffer的容量

StringBuffer的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。

如:StringBuffer buffer = new StringBuffer(1000);

重复String的拼接:
String str = "abcd";
String repeated = StringUtils.repeat(str,3);
分享到:
评论

相关推荐

    String、StringBuilder和StringBuffer的区别

    在Java编程语言中,String、StringBuilder和StringBuffer都是用来处理字符串的类,它们之间存在一些重要的区别,主要涉及到性能和线程安全性。 首先,`String`类代表的是字符串常量,一旦创建,其内容就不能改变。...

    从源码角度简单看StringBuilder和StringBuffer的异同(全面解析)

    StringBuilder和StringBuffer是Java中两个常用的字符串处理类,它们都用于字符串的处理和操作,但它们之间存在一些关键的差异。本文将从源码角度对StringBuilder和StringBuffer的异同进行详细的解析。 ...

    String ,StringBuffer与StringBuilder

    结果显示,使用 StringBuffer 连接字符串的速度非常快,基本上只需要 16 毫秒左右。 由此可见,StringBuffer 的速度几乎是 String 的万倍。当然,这个数据不是很准确,因为循环的次数在 100000 次的时候,差异更大...

    String、StringBuilder、StringBuffer的区别

    再次,从字符串处理方式方面来说,String 是字符串常量,StringBuilder 和 StringBuffer 是字符串变量。String 的不可改变性使得每次操作时都需要创建新的对象,而 StringBuilder 和 StringBuffer 的可改变性使得...

    String StringBuffer和StringBuilder区别之源码解析

    在Java中,字符串是我们经常使用的数据类型,而String、StringBuffer和StringBuilder是Java中三种常用的字符串类。在这篇文章中,我们将从源码角度对String、StringBuffer和StringBuilder进行深入分析,了解它们之间...

    StringBuilder拼接字符串

    C# StringBuilder 拼接字符串 字符串转换工具 StringBuilder比StringBuffer运行速度要快,因为StringBuilder是针对于单线程的,所这它是非线程安全的。普通情况下建议使用StringBuilder。

    String、StringBuffer、StringBuilder的使用方法

    在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`是处理字符串的三个重要类,它们各自有特定的使用场景和优缺点。理解它们的差异对于编写高效的代码至关重要。 **String类** `String`是不可变的类,...

    Java编程中“为了性能”尽量要做到的一些地方

    尽量使用StringBuilder和StringBuffer进行字符串连接 在拼接字符串时,使用`StringBuilder`(非线程安全)或`StringBuffer`(线程安全)比直接使用`+`操作符更加高效,因为后者会在每次拼接时创建新的字符串对象。...

    String及StringBuffer和StringBuilder的区别

    String、StringBuffer 和 StringBuilder 是 Java 语言中三种不同类型的字符串处理方式,它们之间存在着明显的性能和线程安全性差异。 String String 类型是不可变的对象,每次对 String 对象进行改变时都会生成一...

    StringBuilder字符串拼接工具

    这是因为每次使用`+`进行字符串连接时,Java都会创建新的`String`对象,这在内存管理和效率上都是不理想的。而`StringBuilder`则允许我们在一个可变的对象中添加字符,避免了频繁的内存分配。 标题"StringBuilder...

    sql的封装,不需要使用StringBuffer进行字符串拼接

    首先,`StringBuffer`或`StringBuilder`在Java中用于构建可变字符串,它们在循环中拼接字符串时比直接使用`+`操作符更有效率。然而,这种字符串拼接方式在处理大量数据或者频繁拼接时,容易导致内存开销过大,因为...

    字符串连接方面测试时间

    综上所述,虽然“+”运算符提供了一种简洁直观的字符串连接方式,但在性能敏感的应用中,特别是在循环或高并发环境下,采用`StringBuffer`(或在JDK 5.0及以后版本中考虑使用非线程安全但更为高效的`StringBuilder`...

    Java StringBuilder和StringBuffer源码分析

    `append()`方法是`StringBuilder`和`StringBuffer`中字符串拼接的核心。 三、线程安全与效率 `StringBuilder`和`StringBuffer`的主要区别在于线程安全性。`StringBuilder`没有采取任何同步措施,因此在多线程环境下...

    String和StringBuilder、StringBuffer的区别1

    在Java编程语言中,`String`、`StringBuilder`和`StringBuffer`是处理字符串的三种主要类型,它们各自具有不同的特性和使用场景。下面将详细解释它们之间的主要区别。 首先,`String`类是最基本的字符串类型,它...

    Java字符串连接效率[参照].pdf

    本文主要讨论了Java中的String、StringBuilder和StringBuffer三个类在字符串连接方面的性能差异。 首先,String类在Java中是不可变的,这意味着一旦创建,其值就不能改变。字符串常量存储在常量池中,这有助于节省...

    将输入的字符串反转 java

    这两个类提供了append()和reverse()方法,非常适合进行字符串操作。StringBuilder适用于单线程环境,而StringBuffer是线程安全的。以下是一个使用StringBuilder的例子: ```java public class StringReverse { ...

    StringBuffer 和 StringBuilder 类

    在Java编程中,当我们需要对字符串进行多次修改时,StringBuffer和StringBuilder类成为首选。这两个类提供了一种高效且灵活的方式来处理字符串,与不可变的String类相比,它们能避免创建大量未使用的对象,从而提高...

    java String、StringBuilder和StringBuffer的区别详解

    Java中的`String`、`StringBuilder`和`StringBuffer`都是用来处理字符串的类,它们各自有不同的特性和适用场景。在理解它们之间的区别之前,我们首先要知道它们的共同点。 **共同点:** 1. **都是字符串类**:这三...

Global site tag (gtag.js) - Google Analytics