私は次のような Java の本を読んだことがあります。
a
String
は不変であるため、使用するStringBuffer
方が効率的です。
String
インスタンスは不変であることを理解しています。
StringBuffer
また、文字列の処理が通常よりも効率的であることも理解しています。
String
しかし、私が解決できないのは、これら 2 つの概念を結び付けるもの、つまり、不変であることがどのように役立つのStringBuffer
かということです。
ありがとう :)
私は次のような Java の本を読んだことがあります。
a
String
は不変であるため、使用するStringBuffer
方が効率的です。
String
インスタンスは不変であることを理解しています。
StringBuffer
また、文字列の処理が通常よりも効率的であることも理解しています。
String
しかし、私が解決できないのは、これら 2 つの概念を結び付けるもの、つまり、不変であることがどのように役立つのStringBuffer
かということです。
ありがとう :)
String は不変であるため、String を連結するなど、String を操作するには、新しい String オブジェクトを作成する必要があります。明らかに、既存の String オブジェクトの状態を変更することはできないためです。一方、StringBuffer または StringBuilder では、1 つのオブジェクトを作成し、その状態を変更するだけです。たとえば、for ループで主要な String 連結を行っている場合、このオブジェクトの作成は非常にコストがかかる可能性があります。
そうは言っても、ここでは大規模な連結を伴わない単純な文字列連結に批判的な多くの投稿を目にします。そのような状況では、StringBuffer または StringBuilder を使用することは時期尚早で不必要な最適化の例です。
また、アプリケーションが複数のスレッドでオブジェクトにアクセスする必要があり、これが発生する余分なオーバーヘッドを気にしない場合を除き、StringBuffer よりも優先的に StringBuilder を使用する必要があることに注意してください。
つまり、文字列は不変であるため、基になる文字列を変更するたびに新しいオブジェクトを作成するわけではないため、文字列操作には StringBuffer (または StringBuilder) を使用することをお勧めします。
しかし、私が理解できないのは、これら2つの概念を結び付けるものです。つまり、不変であるStringはStringBufferにどのように役立つのでしょうか。
そうではありません。引用した文章を誤解しているだけだと思います。
「文字列は不変であるため、StringBufferを使用する方が効率的です。」
StringBufferは(特定のタスクにとって)比較的効率的なオプションであると言っています。言い換えると、「文字列は不変であるため、[特定のタスクに文字列を使用するよりも]StringBufferを使用する方が効率的です。」
StringBuffer
Stringが不変でない場合よりも、絶対的に高速であると言っているわけではありません。確かに、それは私が引用を読む方法ではありません...そしてそれも本当の声明ではありません。
他のすべての投稿は間違いなく質問に答えています。StringBuilder
常に選択する必要があることを付け加えておきますStringBuffer
。 StringBuffer
組み込みのスレッド同期があります。これは、ほとんど必要のない大量のロック オーバーヘッドです。 StringBuilder
にはこれがないため、高速です。
実際、スレッドセーフが必要な場合でも、を使用しない非常に良い理由がいくつかありStringBuffer
ます。
不変の概念は、この例で簡単に説明できます
String s1 = "Hello";
String s2 = "Hi";
String s3 = "Hello";
if (s1 == s2){ System.out.println("s1==s2");}
if (s1 == s3){ System.out.println("s1==s3");}
s1 = "Hi";
if (s1 == s2){ System.out.println("s1==s2");}
if (s1 == s3){ System.out.println("s1==s3");}
このコードを実行すると、 と が得られ
s1==s3
ますs1==s2
。この例は何を説明していますか?
s1 を作成したとき、コンパイラは文字列テーブルに文字列 "Hello" を作成しました (正確な名前は覚えていません)。s2 を作成すると、新しいオブジェクト "Hi" が作成されます。s3 を作成すると、コンパイラは文字列テーブルにオブジェクト "Hello" が既に存在することを認識します。したがって、s1=s3 (メモリー万力) です。値「hi」を s1 に割り当てたときにも同じことが起こりました。コンパイラは、「hi」が s3 によってポイントされているメモリに既にあることを確認できたため、s1 もポイントしました。
StringBuffer の場合、コンパイラはメモリをオブジェクトに割り当てます。これは、String の場合のように "プール" ではなく操作できます。