Bra*_*ace 4 java string design-patterns
我理解java的字符串实习的基本思想,但我想弄清楚它发生在哪些情况,以及我需要做哪些自己的轻量级.
有点相关:
他们一起告诉我这String s = "foo"很好而且String s = new String("foo")很糟糕,但没有提到任何其他情况.
特别是,如果我解析一个有很多重复值的文件(比如一个csv),Java的字符串实习会覆盖我还是我需要自己做一些事情?关于字符串实习是否适用于我的其他问题,我得到了相互矛盾的建议
完整的答案有几个片段,所以我在这里总结一下:
默认情况下,java仅实现编译时已知的字符串. String.intern(String)可以在运行时使用,但它执行得不是很好,因此它只适用于较小数量的Strings,你肯定会重复很多次.对于较大的Strings系列,它是拯救的番石榴(参见ColinD的回答).
Col*_*inD 20
Guava为您提供的一个选择是使用Interner而不是使用String.intern().String.intern()与之不同,Guava Interner使用堆而不是永久生成.此外,您可以选择String使用弱引用来实现Strings,这样当您使用这些引用时,Interner不会阻止它们被垃圾收集.但是,如果你使用Interner这种方式,当你完成字符串时它就被丢弃了,你可以使用强引用Interners.newStrongInterner()代替可能更好的性能.
Interner<String> interner = Interners.newWeakInterner();
String a = interner.intern(getStringFromCsv());
String b = interner.intern(getStringFromCsv());
// if a.equals(b), a == b will be true
Run Code Online (Sandbox Code Playgroud)
不要在代码中使用String.intern().如果你可能得到20个或更多不同的字符串,至少不会.根据我的经验,String.intern当你有几百万个字符串时,使用会减慢整个应用程序的速度.
要避免重复的String对象,只需使用HashMap.
private final Map<String, String> pool = new HashMap<String, String>();
private void interned(String s) {
String interned = pool.get(s);
if (interned != null) {
return interned;
pool.put(s, s);
return s;
}
private void readFile(CsvFile csvFile) {
for (List<String> row : csvFile) {
for (int i = 0; i < row.size(); i++) {
row.set(i, interned(row.get(i)));
// further process the row
}
}
pool.clear(); // allow the garbage collector to clean up
}
Run Code Online (Sandbox Code Playgroud)
使用该代码,您可以避免一个CSV文件的重复字符串.如果您需要更大规模地避开它们,请pool.clear()在另一个地方打电话.
| 归档时间: |
|
| 查看次数: |
3887 次 |
| 最近记录: |