我已经对此进行了搜索,但我找不到为什么 StringBuilder 的 ensureCapacity() 方法不会通过仅加倍加二来延长旧容量。
所以,当默认容量 16 已满时,除非整个字符串长度不超过 34,否则下一个加长值将是 34。为什么不应该是 32?
我最好的猜测是考虑一个空字符'\u0000',但我不确定。谁能告诉我为什么?
最佳答案
我相信这与一种简单但有点愚蠢的方法有关,以确保非常小的字符串的角盒。
例如,如果我有字符串
""
我只是把它翻倍,我没有足够的大小来存放其他任何东西。如果我将它加倍并添加少量恒定的空格,我可以确保我的新值大于旧值。
那为什么要加二呢?可能是一个小的性能改进。通过添加两个而不是 1,我可以避免小扩展的中间扩展(下面详述 0 到 10 个字符)
"" => expand => "1" => expand => "123" expand => "1234567" expand => "123456789012345"
相比于 4 展开
"" => expand => "12" => expand => "123456" => expand => "123456789012"
这是 3 扩展。这也适用于一个字符字符串(扩展到 10 个字符)
"1" => expand => "1234" => expand => "1234567890"
而 1 char 扩展例程看起来像
"1" => expand => "123" => expand => "1234567" => expand => "123456789012345"
最后,增加 2 的增量往往会在大约 50% 的时间里进行字对齐,而增加的 1 或 3 的增量会在大约 25% 的时间里做到这一点。虽然这看起来没什么大不了的,但如果不调用昂贵的中断调用来重写 CPU 中的读取,某些架构就无法适应非对齐读取,从而导致各种性能问题。
关于Java StringBuilder(StringBuffer) 的 ensureCapacity() : Why is it doubled and incremented by 2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45094521/
我最近读了一篇不错的post关于在Ruby中使用StringIO。不过,作者没有提到的是StringIO只是一个“I”。没有“哦”。你不能这样做,例如:s=StringIO.newsshouldbe"foo\nbar"#=>reallyis''`Ruby确实需要一个StringBuffer,就像Java那样。StringBuffers有两个重要的用途。首先,它们让您测试Ruby的StringIO所做的一半输出。其次,它们对于从小部分构建长字符串很有用——Joel一遍又一遍地提醒我们,否则会非常非常慢。有好的替代品吗?的确,Ruby中的字符串是可变的,但这并不意味着我们应该始终依赖该功能
StringBuffer是String的增强类文章目录StringBuffer是String的增强类添加删除替换插入长度StringBuffer练习题欢迎评论一起学习,如果觉得本文章对你有帮助,一键三连支持一下1.StringBuffer的直接父类是AbstractStringBuilder2.StringBuffer实现了Serializable即StringBuffer的对象可以串行化3.在父类中AbstractStringBuilder有属性char[]value,不是final在该value数组存放字符串内容,引出存放在堆中的4.StringBuffer是一个final类不能被继承5.
在JDK8中,StringBuffer类有一个toStringCache,而StringBuilder没有。/***AcacheofthelastvaluereturnedbytoString.Cleared*whenevertheStringBufferismodified.*/privatetransientchar[]toStringCache;但是为什么呢?我能想到的一个可能原因是StringBuffer已经同步,因此可以更轻松地实现缓存。或者也许历史上StringBuffer是这样实现的,所以旧代码严重依赖这个特性?鉴于现代JVM具有逃逸分析和偏向锁定,这些差异是否相关?
在Java1.7+上,我们是否仍需要使用StringBuffer.append转换“thisstring”+“should”+“be”+“joined”以获得最佳实践? 最佳答案 1)像"thisstring"+"should"+"be"+"joined"这样的常量表达式(JLS15.28)不需要StringBuilder因为它是在编译时计算成一个字符串“这个字符串应该加入”2)对于非常量表达式,编译器将自动应用StringBuilder。也就是说,"string"+var等同于newStringBuilder().append("
大家下午好,我正在使用java.lang.StringBuilder存储一些字符。我不知道我要提前存储多少个字符,除了:60%的情况下,它只有(恰好)7个字符39%的时间是(大约)3500个字符1%的时间,大约是20k个字符我们如何计算应该使用的最佳初始缓冲区长度?目前我正在使用newjava.lang.StringBuilder(4000)但那只是因为我以前懒得想。 最佳答案 这里有两个因素:时间和内存消耗。该时间主要受java.lang.AbstractStringBuilder.expandCapacity()调用次数的影响。
您是否考虑过Java编程语言的这一变化的含义?String类被认为是一个不可变的类(这个决定是经过深思熟虑的)。但是字符串连接真的很慢,我自己对它进行了基准测试。于是StringBuffer诞生了。真的很棒的类(class),同步而且非常快。但是有些人对某些同步块(synchronizedblock)的性能成本不满意,于是引入了StringBuilder。但是,当使用String连接不多的对象时,类的不变性使其成为实现线程安全的一种非常自然的方式。当我们要管理几个String时,我可以理解StringBuffer的使用。但是,这是我的第一个问题:例如,如果您要附加10个或更少的字符串,
publicstaticvoidmain(String[]args){HashSetset=newHashSet();set.add(newStringBuffer("abc"));set.add(newStringBuffer("abc"));set.add(newStringBuffer("abc"));set.add(newStringBuffer("abc"));System.out.println(set);}输出:[abc,abc,abc,abc]在上面的代码中,我多次添加了StringBuffer("abc")的对象,Set添加了它,但Set从不添加重复项。
给定以下代码:StringBufferstr2=newStringBuffer("Idon't");StringBufferstr3=str2.append("getit.");if(str2==str3){System.out.println("Equal");}我的讲师说,在这种情况下str2和str3将引用同一个对象并且字符串“Idon'tgetit”将被插入到“Stringpool”中。我想我明白为什么str2和str3现在将引用同一个对象,但为什么字符串“我不明白”。str3赋值发生时进入字符串池?例如,如果我这样做:Strings="abcd";然后我知道现在字符串“abc
我正在用Java1.6编写一个webapp并在tomcat中运行它。虽然我没有进行任何显式线程处理,但我想知道Spring和Tomcat在幕后发生了什么。使用StringBuilder而不是StringBuffer会遇到任何问题吗? 最佳答案 如果您使用的是局部变量,则可以安全地使用StringBuilder。每个线程都将获得自己的实例。 关于java-我应该为Web应用程序使用StringBuilder还是StringBuffer?,我们在StackOverflow上找到一个类似的问题
我知道StringBuffer和StringBuilder的区别。readhere!一般来说,正如javadoc所说,Wherepossible,itisrecommendedthatthisclassbeusedinpreferencetoStringBufferasitwillbefasterundermostimplementations.但是,StringBuilder的javadoc也说:InstancesofStringBuilderarenotsafeforusebymultiplethreads.Ifsuchsynchronizationisrequiredthenit