4

Java で StringBuffer を使用する場合、スペースを再割り当てする必要がある場合に追加機能をどのように実装するのか疑問に思っています。

たとえば、現在割り当てられているスペースよりも長い文字列を追加した場合、メソッドの詳細でこれをどのように管理しますか?

4

2 に答える 2

5

ソースはJDKダウンロードに含まれています。src.zipファイルを探してください(私のものはProgram Files(x86)\ Java \ jdk1.6.0_01 \ src.zipにあります)。抽出後、java / langに移動するだけで、StringBuffer.java、StringBuilder.java、およびAbstractStringBuilder.javaを調べることができます。

この実装では、AbstractStringBuilderの「expandCapacity」が容量を計算し、Arrays.copyOf()を実行してバッファーを拡張するように見えます。オーバーフロー状態を防ぐために、最初のチェックは0未満であることに注意することも興味深いです。

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);
}
于 2010-10-21T02:25:56.343 に答える
4

Apache Harmony の実装は、 のメソッドに依存してAbstractStringBuilder追加/削除を管理します ( StringBuffer extends AbstractStringBuilder)。

AbstractStringBuilderchar現在の「文字列」を保持するために、文字バッファー (つまり、s の配列) を保持します。任意のオブジェクトの次の文字列表現をこのバッファに追加するとき、バッファに十分なスペースがあるかどうかをチェックし、十分なスペースがない場合は、新しい文字バッファを割り当て、古いバッファをコピーしてから、新しい文字列をそのバッファに追加します。の内部からそれを収集できますenlargeBuffer

private void enlargeBuffer(int min) {
    int newSize = ((value.length >> 1) + value.length) + 2;
    char[] newData = new char[min > newSize ? min : newSize];
    System.arraycopy(value, 0, newData, 0, count);
    value = newData;
    shared = false;
 }

value...そして、このメソッドは、 (char バッファーを保持するプライベート メンバー) の容量を超えると、任意の追加メソッドで呼び出されます。

final void append0(char chars[]) {
    int newSize = count + chars.length;
    if (newSize > value.length) {
         enlargeBuffer(newSize);
     }
     System.arraycopy(chars, 0, value, count, chars.length);
     count = newSize;
}

標準の OpenJDK 実装はかなり似ています。ここでも、 StringBuffer はAbstractStringBuilderに依存しています。

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

文字配列をヌル文字でパディングして total sizeにArrays.copyOfコピーすることに注意してください。これは、基本的に Harmony アプローチの呼び出しと同等です。繰り返しますが、同様に、次の文字列セグメントを追加するのに十分なスペースがない場合、メソッドが呼び出されます。valuenewCapacitynew char[...]expandCapacity

public AbstractStringBuilder append(String str) {
    if (str == null) str = "null";
    int len = str.length();
    if (len == 0) return this;
    int newCount = count + len;
    if (newCount > value.length)
         expandCapacity(newCount);
    str.getChars(0, len, value, count);
    count = newCount;
    return this;
}
于 2010-10-21T02:14:27.583 に答える