ループ内で StringBuilder を使用し、空にして空のStringBuilder
で開始したいx回の反復ごとに、.NET StringBuilder.Clear inのようなメソッドが表示されません。ドキュメントは、 delete メソッドだけで、非常に複雑に見えます。
それでは、JavaでStringBuilder
を整理するための最良の方法は何ですか?
うまくいく2つの方法:
stringBuilderObj.setLength(0)
を使用してください。new StringBuilder()
で新しいものを割り当てます。StringBuilderをリセットするためにsetLength(0)
を使用すること、または各反復で新しいものを作成すること、の2つの選択肢が基本的にあります。どちらも用途に応じて長所と短所があります。
StringBuilderの予想される容量を事前に知っている場合は、毎回新しい容量を作成することは、新しい長さを設定するのと同じくらい速くなるはずです。各StringBuilderは比較的短命であり、gcはそのために最適化されているため、ガベージコレクタも役立ちます。
容量がわからない場合は、同じStringBuilderを再利用するほうが速いかもしれません。追加時に容量を超えるたびに、新しいバッキング配列を割り当て、以前のコンテンツをコピーする必要があります。同じStringBuilderを再利用することで、何度か繰り返した後に必要な容量に達するので、それ以降はコピーされません。
delete
はそれほど複雑ではありません。
myStringBuilder.delete(0, myStringBuilder.length());
次のこともできます。
myStringBuilder.setLength(0);
StringBuilderまたはStringBufferのソースコードを見ると、setLength()呼び出しは文字配列のインデックス値をリセットするだけです。 setLengthメソッドを使用しているIMHOは、常に新しい割り当てよりも高速になります。より明確になるように、彼らはメソッドを 'clear'または 'reset'と命名するべきです。
私はsb.setLength(0);
に投票するつもりですが、それが1つの関数呼び出しであるだけでなく、 実際にはその配列を別の配列にコピーしないためです sb.delete(0, builder.length());
のように。残りの文字を0にして、長さ変数を新しい長さに設定するだけです。
here at setLength
関数とdelete0
関数から私の主張を検証するためにそれらの実装を調べることができます。
sb.delete(0, sb.length())
またはsb.setLength(0)
を使用して、新しいStringBuilder()を作成しないでください。
パフォーマンスについては、この関連記事を参照してください。 StringBuilderをループ内で再利用する方が良いですか?
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
簡単な方法です。
パフォーマンスが主な関心事である場合...皮肉なことに(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());
}
}
私はここでの答えの多くが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
がユーザーとのインターフェースの目的で使用される場合。