StringBuffer类中的ensureCapacity(int minimumCapacity)方法

时间:2014-10-16 12:09:20

标签: java stringbuffer

根据oracle文档,请参阅此链接here

public void ensureCapacity(int minimumCapacity)

Ensures that the capacity is at least equal to the specified minimum. 
If the current capacity is less than the argument, then a new internal array 
is allocated with greater capacity. 

The new capacity is the larger of:
The minimumCapacity argument.
Twice the old capacity, plus 2.
If the minimumCapacity argument is nonpositive, this method takes no action and simply returns.

我试图用代码示例清除它:

    StringBuffer buff1 = new StringBuffer("tuts point");
    System.out.println("buffer1 = " + buff1);        // lenght = 10

    // returns the current capacity of the string buffer 1
    System.out.println("Old Capacity = " + buff1.capacity());  // capacity = 16+10=26 characters
    /*
     * increases the capacity, as needed, to the specified amount in the
     * given string buffer object
     */
    // returns twice the capacity plus 2
    buff1.ensureCapacity(30);
    System.out.println("New Capacity = " + buff1.capacity()); // 26*2 + 2 = 54

如果ensureCapacity方法中的minimumCapacity参数介于27-53之间,那么我确实得到了预期的答案(返回两倍的容量再加上2)。 但是,如果参数为> = 55,则容量仅等于此参数。

    // does not return (twice the capacity plus 2)
    buff1.ensureCapacity(55);
    System.out.println("New Capacity = " + buff1.capacity());  // 55

为什么55这里是答案?

2 个答案:

答案 0 :(得分:2)

这是由于AbstractStringBuilder类的调用:

void expandCapacity(int minimumCapacity) {
    int newCapacity = value.length * 2 + 2;
    if (newCapacity - minimumCapacity < 0)
        newCapacity = minimumCapacity;
    if (newCapacity < 0) {
        if (minimumCapacity < 0) // overflow
            throw new OutOfMemoryError();
        newCapacity = Integer.MAX_VALUE;
    }
    value = Arrays.copyOf(value, newCapacity);
}

因此,当它增加容量时,它会将容量增加至少(2 *原始容量)+ 2,增加到所提供的值,以较大者为准。

如果容量是26,那么你通过30:

(26 * 2)+ 2 = 54,这超过30,所以新容量将为54.

如果容量是26,那么你通过55:

(26 * 2)+ 2 = 54,小于55,所以新容量将为55.

答案 1 :(得分:1)

我确信答案将是vm的实现细节,但是

例如

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/StringBuffer.java#StringBuffer.ensureCapacity%28int%29

public synchronized void More ...ensureCapacity(int minimumCapacity) {
       if (minimumCapacity > value.length) {
            expandCapacity(minimumCapacity);
        }
    }

AbstractStringBuilder

中调用expandCapacity

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/AbstractStringBuilder.java#AbstractStringBuilder.expandCapacity%28int%29

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);
     }

但是我没有看到它返回55.所以更多的代码探索。是需要的(这也是openjdk的来源。不确定发生了什么变化或与你的vm不同