StringBuilder容量()
我注意到capacity
方法没有逻辑方式返回StringBuilder
容量…有时它的值等于字符串长度,其他时间它更大……
知道哪个是逻辑的等式?
当您追加到StringBuilder
,会发生以下逻辑:
if (newCount > value.length) { expandCapacity(newCount); }
其中newCount
是所需的字符数, value.length
是缓冲区的当前大小。
expandCapacity
只是增加了后台char[]
的大小
ensureCapacity()
方法是调用expandCapacity()
的公共方法,其文档说:
确保容量至少等于指定的最小值。 如果当前容量小于参数,则分配具有更大容量的新内部arrays。 新容量是更大的:
- minimumCapacity参数。
- 旧容量的两倍加2。
如果minimumCapacity参数是非正的,则此方法不执行任何操作,只返回。
我将尝试用一些例子来解释这一点。
public class StringBuilderDemo { public static void main(String[] args) { StringBuilder sb = new StringBuilder(); System.out.println(sb.length()); System.out.println(sb.capacity()); } }
length()
– 构建器中字符序列的长度,因为此stringbuilder不包含任何内容,其长度将为0。
capacity()
– 已分配的字符空间数。 当您尝试构造具有空内容的stringbuilder时,默认情况下,它将初始化大小设为length + 16,即0 + 16。 所以容量将在这里返回16。
注意:capacity()方法返回的容量始终大于或等于长度(通常大于),并将根据需要自动扩展以适应字符串构建器的添加。
容量函数背后的逻辑:
- 如果不使用任何内容初始化stringbuilder,则默认容量将被视为16个字符的容量。
- 如果使用任何内容初始化stringbuilder,则容量将为内容长度+ 16。
- 向stringbuilder对象添加新内容时,如果当前容量不足以获取新值,则它将增长(先前数组容量+ 1)* 2。
此分析取自实际的StringBuilder.java代码
此函数执行的操作与您预期的不同 – 它为您提供此StringBuilder实例内存此时可以容纳的最大字符数。
String Builder必读
编辑:道歉 – 以下是有关.NET的StringBuilder的信息,并不是与原始问题严格相关。
http://johnnycoder.com/blog/2009/01/05/stringbuilder-required-capacity-algorithm/
StringBuilder为您可能添加的子字符串分配空间(很像List为它包装的数组创建空间)。 如果您想要字符串的实际长度,请使用StringBuilder.Length。
来自API:
每个字符串构建器都有容量。 只要字符串生成器中包含的字符序列的长度不超过容量,就不必分配新的内部缓冲区。 如果内部缓冲区溢出,它会自动变大。
每当你追加某些内容时,都会检查以确保更新的StringBuilder不会超过其容量,如果是,则调整StringBuilder的内部存储大小:
int len = str.length(); int newCount = count + len; if (newCount > value.length) expandCapacity(newCount);
当数据添加到超过其容量的数据时,将根据以下公式重新resize:
void expandCapacity(int minimumCapacity) { int newCapacity = (value.length + 1) * 2; if (newCapacity < 0) { newCapacity = Integer.MAX_VALUE; } else if (minimumCapacity > newCapacity) { newCapacity = minimumCapacity; } value = Arrays.copyOf(value, newCapacity); }
有关更多信息,请参阅JDK随附的src.zip
文件。 (以上摘自1.6 JDK的片段)
这是逻辑:如果你定义一个没有构造函数的StringBuilder
类的新实例,就像new StringBuilder();
默认容量为16.构造函数可以是int
或String
。 对于String
构造函数,默认容量计算如下
int newCapacity = string.length() + 16;
对于int
构造函数,容量计算如下
int newCapacity = intSpecified + 16;
如果将新的String
附加到StringBuilder
并且String
的新长度大于当前容量,则计算容量如下:
int newCapacity = (oldCapacity + 1) * 2;
你可以进入JDK代码并看看它是如何工作的,它基于一个char数组: new char[capacity]
,它类似于ArrayList
工作方式( 何时使用LinkedList over ArrayList? )。 两者都使用数组“硬件高效”,诀窍是分配大量内存并在其中工作,直到你的内存不足并需要下一个大块继续(扩展/增长)。
- Spring Boot忽略@JsonDeserialize和@JsonSerialize
- 如何在我的自定义Wicket模型类中注入Spring bean?
- .foreach和.stream()之间的区别是什么?foreach?
- 在servlet中读取JSON字符串
- 为什么sysout不起作用?
- java.lang.ClassNotFoundException:org.springframework.web.servlet.DispatcherServlet错误
- Java图像转换
- ExecutorService,如何知道所有线程何时完成而不阻塞主线程?
- BackgroundSubtractorMOG2中“history”的含义是什么?