ホームページ  >  記事  >  Java  >  Java の String、StringBuffer、および StringBuilder 文字列クラスを区別する

Java の String、StringBuffer、および StringBuilder 文字列クラスを区別する

高洛峰
高洛峰オリジナル
2017-01-22 10:06:481393ブラウズ

1 String
String: 文字列定数。文字列の長さは不変です。

2 StringBuffer
StringBuffer: 文字列変数 (同期、つまりスレッドセーフ)。文字列の内容を頻繁に変更する場合は、効率性を考慮して StringBuffer を使用することをお勧めします。String 型に変換する場合は、StringBuffer の toString() メソッドを呼び出します。
Java.lang.StringBuffer スレッドセーフな変更可能な文字シーケンス。いつでも特定の文字シーケンスが含まれていますが、そのシーケンスの長さと内容は特定のメソッド呼び出しによって変更できます。文字列バッファは複数のスレッドで安全に使用できます。
StringBuffer の主な操作は追加メソッドと挿入メソッドであり、これらはオーバーロードしてあらゆる種類のデータを受け入れることができます。各メソッドは、指定されたデータを文字列に効果的に変換し、その文字列の文字を文字列バッファーに追加または挿入します。 append メソッドは常にこれらの文字をバッファーの末尾に追加し、insert メソッドは指定された位置に文字を追加します。たとえば、z が現在の内容が "start" である文字列バッファ オブジェクトを参照している場合、このメソッド呼び出し z.append("le") により文字列バッファには "startle" が含まれますが、z.insert(4, " le") は文字列バッファを変更して「starlet」を含めます。

3 StringBuilder
StringBuilder: 文字列変数 (スレッドセーフではありません)。
java.lang.StringBuilder は、JDK5.0 で新しく追加された可変文字シーケンスです。このクラスは StringBuffer 互換の API を提供しますが、同期は保証されません。このクラスは、文字列バッファーが単一スレッドによって使用される場合 (これが一般的な状況です)、StringBuffer のドロップイン置換として設計されています。ほとんどの実装では StringBuffer よりも高速であるため、可能であればこのクラスを優先することをお勧めします。どちらの方法も基本的には同じです。
ほとんどの場合、StringBuilder > StringBuffer。

4 3 つの違い
String 型と StringBuffer の主なパフォーマンスの違い: String は不変オブジェクトであるため、String 型が変更されるたびに新しい String オブジェクトが生成され、ポインタはそのオブジェクトを指します。新しい String オブジェクトなので、内容が頻繁に変更される文字列には String を使用しないことをお勧めします。これは、オブジェクトが生成されるたびに、特にメモリ内に参照されていないオブジェクトが多すぎる場合、システムのパフォーマンスに影響を与えるためです。 GC が動作し始め、パフォーマンスが低下します。
StringBuffer クラスを使用する場合、新しいオブジェクトを生成したりオブジェクト参照を変更したりするのではなく、毎回 StringBuffer オブジェクト自体に対して操作が実行されます。したがって、ほとんどの場合、特に文字列オブジェクトが頻繁に変更される場合には StringBuffer を使用することをお勧めします。
一部の特殊なケースでは、String オブジェクトの文字列連結は、実際には JVM によって StringBuffer オブジェクトの連結として解釈されるため、このような場合、String オブジェクトの速度は StringBuffer オブジェクトより遅くなりません。例:

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

Generate String S1 オブジェクトは StringBuffer よりも遅くありません。実際、JVM では、次の変換が自動的に行われます:

String S1 = “This is only a” + “ simple” + “test”;

JVM は上記のステートメントを

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

として直接処理するため、非常に高速です。ただし、連結された文字列が別の String オブジェクトからのものである場合、JVM はそれを自動的に変換しないため、速度はそれほど速くならないことに注意してください。 例:

String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;

この時点では、JVM は適切に動作します。そのままやってください。
ほとんどの場合、StringBuffer > String。

4. StringBuffer と StringBuilder には、基本的にはほとんど違いはありません。重要な違いは、StringBuffer のほとんどの内部メソッドの前に synchronized というキーワードが付いていることです。 StringBuilder はスレッドセーフではないため、ある程度のパフォーマンスが消費されます。そのため、より効率的です。

public static void main(String[] args) throws Exception {
    String string = "0";
    int n = 10000;
    long begin = System.currentTimeMillis();
    for (int i = 1; i < n; i++) {
      string += i;
    }
    long end = System.currentTimeMillis();
    long between = end - begin;
    System.out.println("使用String类耗时:" + between+"ms");
  
    int n1 = 10000;
    StringBuffer sb = new StringBuffer("0");
    long begin1 = System.currentTimeMillis();
    for (int j = 1; j < n1; j++) {
      sb.append(j);
    }
    long end1 = System.currentTimeMillis();
    long between1 = end1 - begin1;
    System.out.println("使用StringBuffer类耗时:" + between1+"ms");
  
    int n2 = 10000;
    StringBuilder sb2 = new StringBuilder("0");
    long begin2 = System.currentTimeMillis();
    for (int k = 1; k < n2; k++) {
      sb2.append(k);
    }
    long end2 = System.currentTimeMillis();
    long between2 = end2 - begin2;
    System.out.println("使用StringBuilder类耗时:" + between2+"ms");
  }

出力:

使用String类耗时:982ms
使用StringBuffer类耗时:2ms
使用StringBuilder类耗时:1ms

この数値は実行されるたびに異なり、各マシンの状況も異なりますが、String クラスの消費量が大幅に多いことは確かです。他の2つよりもずっと。もう 1 つのポイントは、違いは明らかではありませんが、StringBuffer は StringBuilder よりも消費量が多いことです。



5 使用戦略
(1) 基本原則: 少量のデータを操作したい場合は String を使用し、単一のスレッドで大量のデータを操作したい場合は StringBuilder を使用します。複数のスレッドで大量のデータを処理する場合は、StringBuffer を使用します。
(2) 頻繁なスプライシングには StringBuffer クラスまたは StringBuilder クラスを使用する必要があるため、使用しないでください。これは Java 最適化における重要な原則です。例: String を使用する場合、文字列を結合するときに「+」を使用して JVM 上に一時的な StringBuffer オブジェクトを作成します。同時に、2 つの文字列を結合するには、合計 4 つのオブジェクトを作成する必要があります。 。 物体! (結果を保存する String、2 つの文字列オブジェクト、および一時的な StringBuffer オブジェクト)。 StringBuffer を使用する場合、作成する必要があるのは 2 つのオブジェクトだけです。 StringBuffer オブジェクトと、最終結果を保持する String オブジェクト。
(3) より良いパフォーマンスを得るために、StirngBuffer または StirngBuilder を構築する際には、可能な限り容量を指定する必要があります。もちろん、操作する文字列の長さが 16 文字を超えない場合は、これは必要ありません。容量を指定しないと、パフォーマンスが大幅に低下する可能性があります。
(4) StringBuilder は通常、「+」と同様の関数を完了するためにメソッド内で使用されます。これはスレッドセーフではないため、使用後に破棄できます。 StringBuffer は主にグローバル変数で使用されます。
(5) StirngBuilder を使用すると、同じ状況で StringBuffer を使用した場合と比較して約 10% ~ 15% のパフォーマンス向上しか達成できませんが、マルチスレッドのセキュリティが確保されないリスクがあります。実際のモジュールプログラミングでは、特定のモジュールを担当するプログラマは、そのモジュールがマルチスレッド環境で実行されるかどうかを必ずしも明確に判断できない場合があります。したがって、システムのボトルネックが StringBuffer にあると判断されない限り、次のようになります。 StringBuilder は、モジュールがマルチスレッド モードで実行されない場合にのみ使用できることがわかります。それ以外の場合は、StringBuffer が引き続き使用されます。

Java の String、StringBuffer、および StringBuilder 文字列クラスの分析に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。