String

String:文字列定数、文字列の長さは変更不可です。Java では String は immutable(不変)です。

String クラスには以下の定義が含まれています:

/** The value is used for character storage. */
private final char value[];

/** The offset is the first index of the storage that is used. */
private final int offset;

/** The count is the number of characters in the String. */
private final int count;

文字を格納するための配列は final として宣言されているため、一度しか代入できず、変更することはできません。

StringBuffer(JDK1.0)

StringBuffer:文字列変数(Synchronized、つまりスレッドセーフ)。文字列の内容を頻繁に変更する場合、効率を考慮すると StringBuffer を使用するのが最善です。String 型に変換したい場合は、StringBuffer の toString() メソッドを呼び出せます。

Java.lang.StringBufferスレッドセーフな可変文字シーケンスです。任意の時点で特定の文字シーケンスを含みますが、特定のメソッド呼び出しによってそのシーケンスの長さと内容を変更できます。文字列バッファは複数のスレッドで安全に使用できます。

StringBuffer主な操作は append メソッドと insert メソッドです。これらのメソッドはオーバーロードでき、任意の型のデータを受け付けることができます。各メソッドは、指定されたデータを効率的に文字列に変換し、その文字列の文字を文字列バッファに追加または挿入します。

  • append メソッドは常にこれらの文字をバッファの末尾に追加します。
  • insert メソッドは指定した位置に文字を追加します。

例えば、もしz現在の内容がstartである文字列バッファオブジェクトを参照する場合、このメソッド呼び出しはz.append("le")文字列バッファに ... を含ませますstartle、一方z.insert(4, "le")文字列バッファを変更して、... を含むようにします。starlet 。

StringBuilder(JDK5.0)

StringBuilder:文字列変数(非スレッドセーフ)。内部では、StringBuilder オブジェクトは文字シーケンスを含む可変長配列として扱われます。

java.lang.StringBuilder は可変の文字シーケンスであり、JDK 5.0 で新しく追加されました。このクラスは StringBuffer と互換性のある API を提供しますが、同期は保証しません。このクラスは、文字列バッファが単一のスレッドで使用される場合(これは非常に一般的です)に、StringBuffer の簡易的な代替として使用するように設計されています。

そのコンストラクタは以下のとおりです。

コンストラクタ 説明
StringBuilder() 容量 16 の StringBuilder オブジェクトを作成します(16 個の空要素)
StringBuilder(CharSequence cs) cs を含む StringBuilder オブジェクトを作成し、末尾に 16 個の空要素を追加します。
StringBuilder(int initCapacity) 容量が initCapacity の StringBuilder オブジェクトを作成します。
StringBuilder(String s) s を含む StringBuilder オブジェクトを作成し、末尾に 16 個の空要素を追加します。

ほとんどの場合、StringBuilder > StringBufferこれは主に、前者がスレッドセーフを考慮する必要がないためです。

三者の違い

String 型と StringBuffer の主な性能上の違い:String は不変オブジェクトであるため、String 型を変更するたびに新しい String オブジェクトが生成され、ポインタが新しい String オブジェクトを指すようにします。したがって、内容を頻繁に変更する文字列には String を使用しないほうがよいです。オブジェクトを生成するたびにシステムの性能に影響を与えるからです。特に、メモリ内で参照されないオブジェクトが多くなると、JVM の GC が動作を開始し、性能が低下します。

StringBuffer クラスを使用する場合、毎回 StringBuffer オブジェクト自体に対して操作が行われ、新しいオブジェクトを生成してオブジェクト参照を変更することはありません。したがって、ほとんどの場合、特に文字列オブジェクトが頻繁に変更される場合は、StringBuffer の使用が推奨されます。

特定の状況では、String オブジェクトの文字列連結は、実際には Java コンパイラによって StringBuffer オブジェクトの連結としてコンパイルされるため、このような場合、String オブジェクトの速度は StringBuffer オブジェクトより遅くはありません。例:

String s1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

String s1 オブジェクトを生成する速度は StringBuffer より遅くはありません。実際、Java コンパイラは自動的に次のような変換を行います。

Java コンパイラは上記の最初のステートメントを直接次のようにコンパイルします:

String s1 = “This is only a simple test”;  

したがって速度は非常に速いです。ただし注意すべき点は、連結する文字列が別の String オブジェクトから取得される場合、Java コンパイラは自動変換を行わないため、速度もそれほど速くはありません。例:

String s2 = “This is only a”;  
String s3 = “ simple”;  
String s4 = “ test”;  
String s1 = s2 + s3 + s4;  

この場合、Java コンパイラは素直に元の方法に従って処理します。String の concatenation(つまり +)操作は、StringBuilder(または StringBuffer)の append メソッドを使用して実装されます。このとき、上記の状況では、s2、s3、s4 が String として定義されている場合、連結時に追加の StringBuffer(または StringBuilder)を作成し、その後 StringBuffer を String に変換する必要があります。StringBuffer(または StringBuilder)を使用する場合は、追加の StringBuffer を作成する必要はありません。

使用戦略

  • (1)基本原則:少量のデータを操作する場合は String を使用します。シングルスレッドで大量のデータを操作する場合は StringBuilder を使用します。マルチスレッドで大量のデータを操作する場合は StringBuffer を使用します。

  • (2)頻繁な連結に String クラスの "+" を使用しないでください。その性能は非常に悪いからです。StringBuffer または StringBuilder クラスを使用すべきです。これは Java の最適化において重要な原則の一つです。例:

    String result = "";
    for (String s : hugeArray) {
        result = result + s;
    }
    
    // 使用StringBuilder
    StringBuilder sb = new StringBuilder();
    for (String s : hugeArray) {
        sb.append(s);
    }
    String result = sb.toString();
    

    上記のような状況が発生した場合、明らかに2番目の方法を採用すべきです。なぜなら、1番目の方法では、ループのたびに結果を保存するための String result が作成されます。これ以外は両者は基本的に同じです(jdk1.5 以降のバージョンについては))。

  • (3)より良い性能を得るために、StringBuffer または StringBuilder を構築するときは、できるだけ容量(capacity)を指定してください。もちろん、操作する文字列の長さ(length)が 16 文字以下の場合は指定する必要はありません。容量(capacity)を指定しない場合、デフォルトで容量 16 のオブジェクトが構築されます。容量を指定しないと、性能が著しく低下します。

  • (4)StringBuilder は通常、メソッド内部で次のような機能を実行するために使用されます。+この機能はスレッドセーフではないため、使用後は破棄して構いません。StringBuffer は主にグローバル変数で使用されます。

  • (5)同じ状況下で StringBuilder を使用すると、StringBuffer を使用する場合と比較してわずか 10%〜15% 程度の性能向上しか得られませんが、スレッドセーフではないというリスクを負うことになります。一方、現実のモジュール化プログラミングでは、あるモジュールを担当するプログラマーは、そのモジュールがマルチスレッド環境で実行されるかどうかを明確に判断できるとは限りません。したがって、システムのボトルネックが StringBuffer にあると確認でき、かつ自分のモジュールがマルチスレッドモードで実行されないと確認できる場合にのみ、StringBuilder を採用できます。そうでなければ、やはり StringBuffer を使用してください。

記事の出典:https://blog.csdn.net/kingzone_2008/article/details/9220691