28

純粋な文字列連結よりも文字列ビルダーを使用する利点とトレードオフは何ですか?

new StringBuilder(32).append(str1)
                     .append(" test: ")
                     .append(val)
                     .append(" is changed")
                     .toString();

対言う

str1 + " test: " + val + " is changed".

str1ランダムな 10 文字の文字列です。 str2ランダムな 8 文字の文字列です。

4

2 に答える 2

53

あなたの特定の例では、コンパイラはStringBuilders を内部的に使用して String 連結を行うため、何もありません。ただし、連結がループ内で発生した場合、コンパイラは複数のStringBuilderandStringオブジェクトを作成する可能性があります。例えば:

String s= "" ;
for(int i= 0 ; i < 10 ; i++ )
    s+= "a" ;

上記の 3 行目が実行されるたびに、新しいStringBuilderオブジェクトが作成され、 の内容がs追加され、「a」が追加StringBuilderされ、 が文字列に変換されて に戻されsます。合計10StringBuilder秒と10String秒。

逆に、

StringBuilder sb= new StringBuilder() ;
for(int i= 0 ; i < 10 ; i++ )
    sb.append( "a" );
String s= sb.toString() ;

1StringBuilderと 1のみStringが作成されます。

これの主な理由は、コンパイラが最初のループが 2 番目のループと同等であることを理解し、より効率的な (バイト) コードを生成するほどスマートではなかったためです。より複雑なケースでは、どんなに賢いコンパイラでも知ることは不可能です。この最適化が絶対に必要な場合は、StringBuilder明示的に s を使用して手動で導入する必要があります。

于 2013-08-26T21:40:42.970 に答える
5

簡単な答えはパフォーマンスです。ネイティブの String クラスを使用している場合、不変の文字列を操作します。

  String line = "java";
  String sufix = " is awesome";
  line = line + sufix;

前の 2 つの文字列 (「java」と「is awesome」) から新しい 3 番目の文字列「java is awesome」を作成するよりも、2 つの文字列「java」と「is awesome」を作成します。アプリで使用されなくなったため)。それは遅い解決策です。

より高速なソリューションは、StringBuffer クラスのアプライアンスです。このクラスは、文字列をマージするためのバッファー (名前から明らかです) を提供するスマート アルゴリズムを使用し、その結果、連結プロセス中に最初の文字列を削除しません。

シングル スレッド アプリケーションを作成している場合 (複数のスレッドが同じオブジェクトにアクセスする同時実行性の問題がない場合) は、最初の StringBuffer クラスよりもさらに高速なパフォーマンスを持つ StringBuilder を適用することをお勧めします。

于 2013-08-26T21:59:24.070 に答える