StringBuffer,StringBuilder以及String

栏目: Java · 发布时间: 5年前

内容简介:今天在网上闲逛,看见他提到的问题也很有深度,然后思考了下,想评论来着。然而评论区太小,写不下,所以单独写在这儿。基本上可以当作快问快答来读…

今天在网上闲逛,看见 @姚冬 的一个 回答

他提到的问题也很有深度,然后思考了下,想评论来着。然而评论区太小,写不下,所以单独写在这儿。

基本上可以当作快问快答来读…

为什么 java 中的string不以\0结尾?

  • \0结尾在很大程度上要求 程序员 写规范的代码,如果写出了不规范的代码,那么很容易就内存越界了。
  • 另外,string的内部存储是char[],而为了内存安全,java数组本来就有一个length属性,这时以\0结尾就是一个多余的设计了。
  • String的内部存储也只能是char[]了,如果是其他的方式,比如通过native内部放一个c风格的数组,那么java代码中的char[]和string的转换就要很多内存拷贝操作了。
  • C语言 设计成\0结尾,是为了减少抽象层,让C语言更加贴近硬件

(在语言设计中,)字符串的长度放哪里,放到起始指针的位置,还是起始指针的前面 ?

  • Java中,String的length也就是数组的length,JLS也只是说明了arraylength字节码,没有规定如何实现
  • 不过Hot Spot的实现是,先元数据,再长度,再具体的内容(比如char[])

如果放前面,那么字符串起始指针和内存块起始不一致怎么解决

Java不存在这个问题,我觉得。元数据和length字段都在实际数组之前呢。Java中,访问任何对象之前都要再多一次跳转,跳过元数据(和length)。

字符串拼接的时候把源串复制到目标串结尾,那么目标串剩余内存不够怎么办,重新分配要多一次赋值,频繁拼接性能有问题怎么办

  • 这个问题比较核心,Java的String不可变设计导致了只能单独复制一份来new String。
  • 这个问题,编译器、JVM很难优化,你把单个的字符串拼接操作优化成StringBuilder的append,但是也扛不住我在for循环中频繁append啊。而且每次new一个StringBuilder也是很大的负担。
  • 当然,也有优化的办法,string相加的时候,string内部持有一个String数组,在展示的时候,才拼成最终的String。但这个改动就比较大了。

要不要设计单独的辅助类来解决字符串拼接问题

那这个辅助类怎么设计,要不要考虑线程安全

如果考虑线程安全的话,怎么兼顾性能

现在看来是要一个辅助类的,比如StringBuilder(非线程安全)和StringBuffer(线程安全),但StringBuilder的线程安全也仅仅是每个方法前面加了synchronized而已啊。

然后说性能,我要append一个长度为1000的String,按理来说String不可变,我可以把String存到数组里,build的时候再拼。

但是StringBuilder的实现还是一个一个char拷进StringBuilder,最后拼的时候,再拷了一次。多copy了一次啊。

说到这儿, @RednaxelaFX 也在回答的评论区提到了:

在Oracle JDK / OpenJDK的实现中,无论用StringBuffer还是StringBuilder去作为字符串拼接的底层实现其实都不是最优的——它们俩都不是为append-only场景优化,而是为更通用的可变字符串场景优化的。

然后我看看如何实现:

List暂存一把最后需要的时候直接造个新string

我先去查了下,Apache Commons和Guava里面居然都没有这个实现,这个让我很吃惊。

但是仔细一想,这个优化第三方库确实很难做:

  • List先转成char[],copy了一次。通过这个char[]来new String的时候,还得再copy一次(String和其他对象共享char[]的构造方法是包级别的,不是public的)
  • 如果要做只能使用反射或者unsafe来强行调用了,这样就和实现绑定了,不通用了。

所以现在看来,String的append操作,确实很难优化。要不将String实现搞复杂;要不上层自己写StringBuilder来做。

参考资料:


以上所述就是小编给大家介绍的《StringBuffer,StringBuilder以及String》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深度学习入门

深度学习入门

[ 日] 斋藤康毅 / 陆宇杰 / 人民邮电出版社 / 2018-7 / 59.00元

本书是深度学习真正意义上的入门书,深入浅出地剖析了深度学习的原理和相关技术。书中使用Python3,尽量不依赖外部库或工具,从基本的数学知识出发,带领读者从零创建一个经典的深度学习网络,使读者在此过程中逐步理解深度学习。书中不仅介绍了深度学习和神经网络的概念、特征等基础知识,对误差反向传播法、卷积神经网络等也有深入讲解,此外还介绍了深度学习相关的实用技巧,自动驾驶、图像生成、强化学习等方面的应用,......一起来看看 《深度学习入门》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具