在什么情况下String比StringBuffer更有用; StringBuilder的

时间:2014-07-04 21:04:37

标签: java string

如果stringBuffer& StringBuilder对String很有用,为什么String类没有折旧

2 个答案:

答案 0 :(得分:5)

这是关于每个班级的目的。

String class表示char的字符串或集合(数组),可以对人类具有特定含义。

AbstractStringBuilderpublicStringBuilder的抽象非StringBuffer超类主要用于构建String的内容,然后生成一个完整的String。这是因为String类是不可变的,这意味着String上的任何操作都会生成新的String对象,而StringBuilderStringBuffer上的任何操作都会生效在相同参考的状态,从而节省内存和获得性能。


来自the accepted answer可能重复的问答:

  

如果您的字符串不会更改,请使用String类,因为String对象是不可变的。

请注意,这并不意味着当您不知道其特定值或其值是基本串联的结果时,您无法定义String。这是一个例子:

String name = "Luiggi";
String helloLuiggi = "Hello " + "Luiggi";
String helloName = "Hello " + name;

以上情况:

  • name值为"Luiggi"
  • helloLuiggi值为"Hello Luiggi"。编译器足够聪明,可以理解"Hello ""Luiggi"是文字String值,它们应该生成String和{{1}的单个"Hello "自动连接这不会产生任何性能开销。
  • "Luiggi"值将是连接helloName"Hello "字符串的结果。在这种情况下,编译器将在幕后使用name来提高操作性能。
  

如果您的字符串可以更改(例如:字符串构造中的大量逻辑和操作)并且只能从单个线程访问,那么使用StringBuilder就足够了。

完全正确。这是一个基本示例,用于演示使用纯StringBuilder级联的性能差异,并使用JUnit BenchmarkString构建String

StringBuilder

结果:

  

StringVsStringBuilderTest.stringPerformance:[测量15轮中的10轮,线程:1(连续)]   圆形:0.00 [+ - 0.00],round.block:0.00 [+ - 0.00],round.gc:0.00 [+ - 0.00],GC.calls:1,GC.time:0.00,time.total:0.05,time .warmup:0.02,time.bench:0.03

     

StringVsStringBuilderTest.stringBuilderPerformance:[测量15轮中的10轮,线程:1(顺序)]
  round:0.00 [+ - 0.00],round.block:0.00 [+ - 0.00],round.gc:0.00 [+ - 0.00],GC.calls:0,GC.time:0.00,time.total:0.00,time .warmup:0.00,time.bench:0.00

public class StringVsStringBuilderTest { @Rule public TestRule benchmarkRun = new BenchmarkRule(); static final int TIMES = 1000; @Test public void stringPerformance() { String s = ""; int j = 1; for (int i = 0; i < TIMES; i++) { s = s + j++; if (j == 10) { j = 0; } } System.out.println(s); } @Test public void stringBuilderPerformance() { StringBuilder sb = new StringBuilder(); int j = 1; for (int i = 0; i < TIMES; i++) { sb.append(j++); if (j == 10) { j = 0; } } System.out.println(sb.toString()); } } 常量值更改为10000:

  

StringVsStringBuilderTest.stringPerformance:[测量15轮中的10轮,线程:1(连续)]   round:0.04 [+ - 0.02],round.block:0.00 [+ - 0.00],round.gc:0.00 [+ - 0.00],GC.calls:3,GC.time:0.00,time.total:0.66,time .warmup:0.27,time.bench:0.38

     

StringVsStringBuilderTest.stringBuilderPerformance:[测量15轮中的10轮,线程:1(顺序)]
  round:0.00 [+ - 0.00],round.block:0.00 [+ - 0.00],round.gc:0.00 [+ - 0.00],GC.calls:0,GC.time:0.00,time.total:0.01,time .warmup:0.00,time.bench:0.00

在最后一个例子中,我们可以看到两者之间的时间和GC调用的差异。不过,如果你真的不介意0.66秒的时间来连接10000个单值并且有足够的RAM,那么继续使用TIMES连接(但要注意它不是最好的设计你做错了什么。)

  

如果您的字符串可以更改,并且将从多个线程访问,请使用String,因为StringBuffer是同步的,因此您具有线程安全性。

虽然这是真的,但看起来您可以使用其他结构将StringBuffer存储为BlockingQueue,然后使用String

答案 1 :(得分:1)

他们完全不同。

String是不可变的且具有可比性,因此可以安全地用作集合的元素。

StringBuilder是可变的,无法比较,但它可用于操纵其内容。您绝不能在集合中使用可变对象或作为地图的键,并且应避免在许多其他情况下使用它们。

StringBufferStringBuilder类似,但它也是线程安全的。由于字符串操作很少分散在多个线程中,StringBuffer在实践中确实不如StringBuilder有用,主要是出于历史原因。