web-dev-qa-db-ja.com

StringBuilder容量()

capacityメソッドが論理的な方法なしでStringBuilder容量を返すことに気づきました...その値が文字列の長さと等しい場合とそれより大きい場合があります...

その論理がどれであるかを知るための方程式はありますか?

15
xdevel2000

StringBuilderに追加すると、次のロジックが発生します。

_if (newCount > value.length) {
    expandCapacity(newCount);
}
_

ここで、newCountは必要な文字数、_value.length_はバッファの現在のサイズです。

expandCapacityは単にバッキングのサイズを大きくします_char[]_

ensureCapacity()メソッドはexpandCapacity()を呼び出す公的な方法であり、そのドキュメントには次のように書かれています。

容量が少なくとも指定された最小値と等しいことを確認します。現在の容量が引数よりも小さい場合は、新しい内部配列に大きな容量が割り当てられます。新しい容量は、次のうち大きい方です。

  • MinimumCapacity引数。
  • 古い容量の2倍、プラス2。

MinimumCapacity引数が正でない場合、このメソッドはアクションを実行せず、単に戻ります。

13
Bozho

これをいくつかの例で説明しようと思います。

_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だけ増加します。

この分析は 実際のStringBuilder.Javaコード から取得されます

11
user1923551

この関数は、予想とは異なる動作をします。この関数は、このStringBuilderインスタンスメモリが現時点で保持できる最大文字数を提供します。

文字列ビルダーは読み取る必要があります

4
InsertNickHere

ロジックは次のとおりです。コンストラクタなしでStringBuilderクラスの新しいインスタンスを定義する場合、たとえばnew StringBuilder();のデフォルト容量は16です。コンストラクタはintのいずれかです。またはStringStringコンストラクターの場合、デフォルトの容量は次のように計算されます

int newCapacity = string.length() + 16;

intコンストラクターの場合、容量は次のように計算されます

int newCapacity = intSpecified + 16;

新しいStringStringBuilderに追加され、Stringの新しい長さが現在の容量よりも大きい場合、容量は次のように計算されます。

int newCapacity = (oldCapacity + 1) * 2;
1
Ayokunle Paul

編集:お詫び-以下は.NETのStringBuilderに関する情報であり、元の質問と厳密には関連していません。

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

StringBuilderは、追加する可能性のある部分文字列にスペースを割り当てます(Listがラップする配列にスペースを作成するのと同じように)。文字列の実際の長さが必要な場合は、StringBuilder.Lengthを使用します。

1
Alex Humphrey

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から取得した上記のスニペット)

1
Catchwa

JDKコードの内部に移動して、それがどのように機能するかを確認できます。これは、char配列に基づいています。new char[capacity]、これはArrayListの動作と似ています( ArrayListよりもLinkedListを使用する場合 )。どちらも「ハードウェア効率」を高めるために配列を使用します。トリックは、メモリの大きなチャンクを割り当て、メモリが不足して次の大きなチャンクが続行(拡張/拡張)する必要があるまでその中で作業することです。

0

in 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
0
HenryChuang