web-dev-qa-db-ja.com

JavaでStringBuilderを使用する場合

Javaの文字列連結にはStringBuilderを使うのが一般的に好ましいとされています。これはいつもそうですか?

つまり、StringBuilderオブジェクトを作成し、append()メソッドを呼び出し、最後にtoString()を2つの文字列に対して既存の文字列と+演算子で連結することによるオーバーヘッドなのでしょうか。

そのようなしきい値がある場合、それは何に依存しますか(おそらく文字列の長さ、しかしどのように)。

そして最後に、2つ、3つ、4つの文字列のような小さなケースでは、+連結の読みやすさと簡潔さをStringBuilderのパフォーマンスと交換しますか。

通常の連結にStringBuilderを明示的に使用することは、 廃止されたJava最適化のヒント および Java urbanで廃止されたとされています神話 .

330
kostja

ループ内で文字列連結を使用すると、次のようになります。

String s = "";
for (int i = 0; i < 100; i++) {
    s += ", " + i;
}

その場合はStringBuilderの代わりにStringBufferStringではなく)を使用するべきです。

あなたが単一の声明を持っているならば、

String s = "1, " + "2, " + "3, " + "4, " ...;

コンパイラは自動的にStringを使用するため、この場合はStringBuildersを使用できます。

463
Ralph

ラルフの答えは素晴らしいです。 Stringの使い方はBuilderパターンのように見えるので、StringBuilderクラスを使用してStringを作成/装飾します。

public String decorateTheString(String orgStr){
            StringBuilder builder = new StringBuilder();
            builder.append(orgStr);
            builder.deleteCharAt(orgStr.length()-1);
            builder.insert(0,builder.hashCode());
            return builder.toString();
}

String自体ではなく、Stringを構築するためのヘルパー/ビルダーとして使用できます。

49
zawhtut

原則として、常に読みやすいコードを使用し、パフォーマンスが問題となる場合にのみリファクタリングしてください。この特定のケースでは、最近のJDKが実際にコードをStringBuilderバージョンに最適化します。

通常は、ループ内またはコンパイラで最適化できない複雑なコード内で文字列連結を行う場合にのみ、手動で行う必要があります。

37
Riaan Cornelius

ご覧ください: http://www.javaspecialists.eu/archive/Issue068.html および http: //www.javaspecialists.eu/archive/Issue105.html

ご使用の環境で同じテストを行い、新しいJDKまたはJava実装でStringを使用した場合とStringBuilderを使用した場合で、どちらかのタイプの文字列操作が適切に行われるかどうかを確認します。

7
Michał Niklas

コンパイラによっては、文字列連結を同等のStringBuilderに置き換えることができない場合があります。コンパイル時の最適化に頼る前に、あなたのソースがどのコンパイラを使うのかを必ず検討してください。

5

+演算子は内部でpublic String concat(String str)を使います。このメソッドは2つの文字列の文字をコピーするので、2つの文字列の長さに比例したメモリ要件と実行時の複雑さがあります。 StringBuilderはより効率的に機能します。

しかし、ここで を読んだことがあります +演算子を使った連結コードは、Java 4以降のコンパイラではStringBuilderに変更されます。だからこれはまったく問題にならないかもしれません。 (私のコードでこのステートメントに依存しているのであれば、私は本当にこのステートメントをチェックしますが!)

4
spa

2つの文字列の場合はconcatの方が速く、それ以外の場合はStringBuilderのほうが適しています。 連結演算子(+)とconcat() の説明を参照してください。

4

文字列連結の問題点は、関連するすべてのコストでStringオブジェクトがコピーされることです。 StringBuilderはスレッドセーフではないため、Java 5より前のStringBufferよりも高速です。経験則として、ループ内で文字列連結を実行しないでください。これは頻繁に呼び出されることになります。私はここでいくつかの連結をすることを推測します、そしてあなたが数百について話していない限りあなたが傷つくことはないでしょう、そしてこれはもちろんあなたのパフォーマンス要件に依存します。あなたがリアルタイムのものをしているならば、あなたは非常に注意するべきです。

3
Navi

マイクロソフトの認定資料でも、これと同じ問題が解決されています。 .NETの世界では、StringBuilderオブジェクトのオーバーヘッドにより、2つのStringオブジェクトの単純な連結がより効率的になります。私はJavaの文字列についても同様の答えを仮定します。

2
Babak Naffas