web-dev-qa-db-ja.com

StringBuilderをクリアまたは空にする方法

ループ内で StringBuilder を使用し、空にして空のStringBuilderで開始したいx回の反復ごとに、.NET StringBuilder.Clear inのようなメソッドが表示されません。ドキュメントは、 delete メソッドだけで、非常に複雑に見えます。

それでは、JavaでStringBuilderを整理するための最良の方法は何ですか?

552
Hans Olsson

うまくいく2つの方法:

  1. stringBuilderObj.setLength(0)を使用してください。
  2. バッファをクリアする代わりにnew StringBuilder()で新しいものを割り当てます。
643
Marcus Frödin

StringBuilderをリセットするためにsetLength(0)を使用すること、または各反復で新しいものを作成すること、の2つの選択肢が基本的にあります。どちらも用途に応じて長所と短所があります。

StringBuilderの予想される容量を事前に知っている場合は、毎回新しい容量を作成することは、新しい長さを設定するのと同じくらい速くなるはずです。各StringBuilderは比較的短命であり、gcはそのために最適化されているため、ガベージコレクタも役立ちます。

容量がわからない場合は、同じStringBuilderを再利用するほうが速いかもしれません。追加時に容量を超えるたびに、新しいバッキング配列を割り当て、以前のコンテンツをコピーする必要があります。同じStringBuilderを再利用することで、何度か繰り返した後に必要な容量に達するので、それ以降はコピーされません。

282
Jörn Horstmann

deleteはそれほど複雑ではありません。

myStringBuilder.delete(0, myStringBuilder.length());

次のこともできます。

myStringBuilder.setLength(0);
70
krtek

StringBuilderまたはStringBufferのソースコードを見ると、setLength()呼び出しは文字配列のインデックス値をリセットするだけです。 setLengthメソッドを使用しているIMHOは、常に新しい割り当てよりも高速になります。より明確になるように、彼らはメソッドを 'clear'または 'reset'と命名するべきです。

28
Javamann

私はsb.setLength(0);に投票するつもりですが、それが1つの関数呼び出しであるだけでなく、 実際にはその配列を別の配列にコピーしないためです sb.delete(0, builder.length());のように。残りの文字を0にして、長さ変数を新しい長さに設定するだけです。

here at setLength関数とdelete0関数から私の主張を検証するためにそれらの実装を調べることができます。

16
Ahmed Hegazy

sb.delete(0, sb.length())またはsb.setLength(0)を使用して、新しいStringBuilder()を作成しないでください。

パフォーマンスについては、この関連記事を参照してください。 StringBuilderをループ内で再利用する方が良いですか?

6
Tony Meng
StringBuilder s = new StringBuilder();
s.append("a");
s.append("a");
// System.out.print(s); is return "aa"
s.delete(0, s.length());
System.out.print(s.length()); // is return 0

簡単な方法です。

4
javaddroid

パフォーマンスが主な関心事である場合...皮肉なことに(IMO)、 into になるテキストをフォーマットするためのJava構文です。バッファーは、alloc/realloc/garbage collectionよりもCPU上ではるかに時間がかかります。 ...そうですね、あなたが作成して破棄したビルダーの数によってはGCではないかもしれません。

しかし、単純に複合文字列( "Hello World of" + 6E9 + "earthlings。")をバッファに追加するだけでは、全体の問題は重要ではなくなります。

そして、実際に、StringBuilderが関与するコンテンツが単純でString str = "Hi";よりも複雑で長く、長くなる場合(Javaはおそらくバックグラウンドでビルダーを使用します)。

個人的には、GCを悪用しないようにしています。たとえば、デバッグ出力メッセージを書くなどのように、それが緊急火災のシナリオでよく使用されることになっているものであれば、それを別の場所で宣言し、再利用のためにゼロにすると仮定します。

class MyLogger {
    StringBuilder strBldr = new StringBuilder(256);

    public LogMsg( String stuff ) {

        strBldr.setLength(0);

        // ... prepend status level
        strBldr.append("Info");
        // ... prepend timestamp
        strBldr.append(" " + getTimestamp());
        // ... user msg
        strBldr.append(":" + msg);

        log.write(strBldr.toString());
    }
}
2
DevByStarlight

私はここでの答えの多くがStringBuilder.delete(int start, [int] end)に含まれる質の高い方法を欠いているかもしれないと思います。これは返信が遅いことを私は知っています。しかしながら、これは知らされるべきです(そしてもう少し徹底的に説明されるべきです)。

StringBuilderテーブルがあるとしましょう - あなたのプログラムを通して動的に修正したいテーブルです(私が今取り組んでいるものはこれをします)。

StringBuilder table = new StringBuilder();

メソッドをループ処理してコンテンツを変更する場合は、そのコンテンツを使用し、そのコンテンツを破棄して次の反復のためにStringBuilderを削除したい場合は、そのコンテンツを削除できます。

table.delete(int start, int end). 

開始と終了は、削除したい文字のインデックスです。文字数の長さがわからず、すべてを削除したいですか?

table.delete(0, table.length());

今、キッカーのために。 StringBuildersは、前述したように、頻繁に変更されると多くのオーバーヘッドがかかります(そしてスレッド化に関して安全性の問題を引き起こす可能性があります)。そのため、StringBufferを使用してください - 少数の例外を除いてStringBuilderと同じです - あなたのStringBuilderがユーザーとのインターフェースの目的で使用される場合。

2
Thomas