如果stringBuffer和StringBuilder对String很有用,为什么String类不被折旧
这是关于每个班级的目的.
Stringclass表示char可以对人类具有特定含义的字符串或集合(数组).
AbstractStringBuilder(这是抽象非public超类的StringBuilder和StringBuffer)主要用于构建a的内容String然后生成一个整体String.这是因为String类是不可变的,这意味着对a的任何操作都会String生成一个新String对象,而任何操作都会对同一个引用的状态进行操作StringBuilder或处理StringBuffer,从而节省内存并获得性能.
从可能的重复Q/A 的接受答案:
如果您的字符串不会更改,请使用
String类,因为String对象是不可变的.
请注意,这并不意味着您不能String在不知道其特定值或其值是基本串联的结果时定义.这是一个例子:
String name = "Luiggi";
String helloLuiggi = "Hello " + "Luiggi";
String helloName = "Hello " + name;
Run Code Online (Sandbox Code Playgroud)
如果是上述情况:
name价值将是"Luiggi".helloLuiggi价值将是"Hello Luiggi".编译器足够聪明,可以理解它"Hello "并且"Luiggi"是字面值String,它们应该生成单个String自动连接,"Hello "并且"Luiggi"不会产生任何性能开销.helloNamevalue将是连接"Hello "和name字符串的结果.在这种情况下,编译器将使用StringBuilder幕后为您提高操作性能.如果您的字符串可以更改(例如:字符串构造中的大量逻辑和操作)并且只能从单个线程访问,则使用a
StringBuilder就足够了.
这是完全正确的.这里有一个简单的例子来演示使用普通的性能差异String级联和建设String从StringBuilder使用JUnit的基准:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
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.03StringVsStringBuilderTest.stringBuilderPerformance:[测量15轮中的10轮,线程:1(顺序)]
轮: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
将TIMES常量值更改为10000:
StringVsStringBuilderTest.stringPerformance:[测量15轮中的10轮,线程:1(顺序)]
轮: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.38StringVsStringBuilderTest.stringBuilderPerformance:[测量15轮中的10轮,线程:1(顺序)]
轮: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,那么继续使用String连接(但要注意它不是最好的设计而你做错了).
如果您的字符串可以更改,并且将从多个线程访问,请使用
StringBuffer因为StringBuffer是同步的,因此您具有线程安全性.
虽然这是真的,看起来你可以使用另一个结构来存储Strings像a BlockingQueue然后使用Strings.
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |