StringBuilder容量()

时间:2010-07-06 07:17:57

标签: java stringbuilder capacity

我注意到capacity方法在没有逻辑的情况下返回StringBuilder容量 方式......有时它的值等于字符串长度,而其它时间更长......

是否知道哪个是其逻辑?

8 个答案:

答案 0 :(得分:13)

当您追加到StringBuilder时,会发生以下逻辑:

if (newCount > value.length) {
    expandCapacity(newCount);
}

其中newCount是所需字符数,value.length是缓冲区的当前大小。

expandCapacity只会增加支持char[]

的大小

ensureCapacity()方法是调用expandCapacity()的公开方式,其文档说:

  

确保容量至少等于指定的最小值。如果当前容量小于参数,则分配具有更大容量的新内部阵列。新容量是更大的:

     
      
  • minimumCapacity参数。
  •   
  • 旧容量的两倍,再加上2.
  •   
     

如果minimumCapacity参数为非正数,则此方法不执行任何操作,只返回。

答案 1 :(得分:11)

我将尝试用一些例子解释这一点。

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()方法返回的容量始终大于或等于长度(通常大于),并将根据需要自动扩展以适应字符串构建器的添加。

容量功能背后的逻辑:

  1. 如果您没有使用任何内容初始化stringbuilder,则默认容量将被视为16个字符的容量。
  2. 如果使用任何内容初始化stringbuilder,则容量将为内容长度+16。
  3. 当您向stringbuilder对象添加新内容时,如果当前容量不足以获取新值,则它将增长(之前的数组容量+ 1)* 2.
  4. 此分析来自actual StringBuilder.java code

答案 2 :(得分:4)

此函数执行与您预期不同的操作 - 它为您提供此StringBuilder实例内存此时可以容纳的最大字符数。

String Builder must read

答案 3 :(得分:1)

编辑:道歉 - 以下是有关.NET的StringBuilder的信息,与原始问题并不严格相关。

http://johnnycoder.com/blog/2009/01/05/stringbuilder-required-capacity-algorithm/

StringBuilder为您可能添加到它的子字符串分配空间(很像List为它包装的数组创建空间)。如果您想要字符串的实际长度,请使用StringBuilder.Length。

答案 4 :(得分:1)

来自API:

  

每个字符串构建器都有容量。   只要字符的长度   字符串中包含的序列   建造者不超过容量,   没有必要分配新的   内部缓冲区。如果内部   缓冲区溢出,它是自动的   做得更大。

每当你附加某些内容时,都会检查以确保更新的StringBuilder不会超过其容量,如果是,则调整StringBuilder的内部存储大小:

int len = str.length();
int newCount = count + len;
if (newCount > value.length)
  expandCapacity(newCount);

当数据添加到超出其容量的数据时,将根据以下公式重新调整大小:

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的片段)

答案 5 :(得分:1)

这是逻辑: 如果您在没有构造函数的情况下定义StringBuilder类的新实例,那么new StringBuilder();的默认容量为16。 构造函数可以是intString。 对于String构造函数,默认容量计算如下

int newCapacity = string.length() + 16;

对于int构造函数,容量计算方式如下

int newCapacity = intSpecified + 16;

如果新String附加到StringBuilder并且String的新长度大于当前容量,则容量计算如下:

int newCapacity = (oldCapacity + 1) * 2;

答案 6 :(得分:0)

你可以进入JDK代码并看看它是如何工作的,它基于一个char数组:new char[capacity],它类似于ArrayList的工作方式(When to use LinkedList over ArrayList?)。两者都使用数组“硬件高效”,诀窍是分配大量内存并在其中工作,直到你的内存不足并需要下一个大块继续(扩展/增长)。

答案 7 :(得分:0)

在Java 1.8中

public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}

private void ensureCapacityInternal(int minimumCapacity) {
    // overflow-conscious code
    if (minimumCapacity - value.length > 0) {
        value = Arrays.copyOf(value,
                newCapacity(minimumCapacity));
    }
}

例如:

StringBuilder str = new StringBuilder();  
System.out.println(str.capacity()); //16

str.append("123456789012345"); 
System.out.println(str.capacity()); //16

str.append("12345678901234567890"); 
System.out.println(str.capacity()); // 15 + 20 = 35