如果stringBuffer& StringBuilder对String很有用,为什么String类没有折旧
答案 0 :(得分:5)
这是关于每个班级的目的。
String
class表示char
的字符串或集合(数组),可以对人类具有特定含义。
AbstractStringBuilder
(public
和StringBuilder
的抽象非StringBuffer
超类主要用于构建String
的内容,然后生成一个完整的String
。这是因为String
类是不可变的,这意味着String
上的任何操作都会生成新的String
对象,而StringBuilder
或StringBuffer
上的任何操作都会生效在相同参考的状态,从而节省内存和获得性能。
来自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 Benchmark从String
构建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
是可变的,无法比较,但它可用于操纵其内容。您绝不能在集合中使用可变对象或作为地图的键,并且应避免在许多其他情况下使用它们。
StringBuffer
与StringBuilder
类似,但它也是线程安全的。由于字符串操作很少分散在多个线程中,StringBuffer
在实践中确实不如StringBuilder
有用,主要是出于历史原因。