今天在网上闲逛,看见 @姚冬 的一个 回答 。
他提到的问题也很有深度,然后思考了下,想评论来着。然而评论区太小,写不下,所以单独写在这儿。
基本上可以当作快问快答来读…
为什么java中的string不以/0结尾?
(在语言设计中,)字符串的长度放哪里,放到起始指针的位置,还是起始指针的前面 ?
如果放前面,那么字符串起始指针和内存块起始不一致怎么解决
Java不存在这个问题,我觉得。元数据和length字段都在实际数组之前呢。Java中,访问任何对象之前都要再多一次跳转,跳过元数据(和length)。
字符串拼接的时候把源串复制到目标串结尾,那么目标串剩余内存不够怎么办,重新分配要多一次赋值,频繁拼接性能有问题怎么办
要不要设计单独的辅助类来解决字符串拼接问题
那这个辅助类怎么设计,要不要考虑线程安全
如果考虑线程安全的话,怎么兼顾性能
现在看来是要一个辅助类的,比如StringBuilder(非线程安全)和StringBuffer(线程安全),但StringBuilder的线程安全也仅仅是每个方法前面加了synchronized而已啊。
然后说性能,我要append一个长度为1000的String,按理来说String不可变,我可以把String存到数组里,build的时候再拼。
但是StringBuilder的实现还是一个一个char拷进StringBuilder,最后拼的时候,再拷了一次。多copy了一次啊。
说到这儿, @RednaxelaFX 也在回答的评论区提到了:
在Oracle JDK / OpenJDK的实现中,无论用StringBuffer还是StringBuilder去作为字符串拼接的底层实现其实都不是最优的——它们俩都不是为append-only场景优化,而是为更通用的可变字符串场景优化的。
然后我看看如何实现:
List<string>暂存一把最后需要的时候直接造个新string
我先去查了下,Apache Commons和Guava里面居然都没有这个实现,这个让我很吃惊。
但是仔细一想,这个优化第三方库确实很难做:
所以现在看来,String的append操作,确实很难优化。要不将String实现搞复杂;要不上层自己写StringBuilder来做。
参考资料: