文字列を連結するなら演算子ではなくStringBuilderが推奨されるらしいです
文字の連結といえば+
演算子を使ったおなじみの式でしたが、それよりもStringBuilder
が推奨されているという噂を聞きつけました。というわけで今回もいろいろ見ていきます。
StringBuilderとは
文字の可変シーケンスです。このクラスは、StringBufferと互換性があるAPIを提供しますが、同期化は保証されません。このクラスは、文字列バッファが単一のスレッド(一般的なケース)により使用されていた場合のStringBufferの簡単な代替として使用されるよう設計されています。このクラスは、ほとんどの実装で高速に実行されるので、可能な場合は、StringBufferよりも優先して使用することをお薦めします。
今のところは文字列の連結は+
演算子、StringBuilder
、StringBuffer
の3つがありStringBuffer
よりStringBuilder
のほうが処理速度が速いので優先して使ったほうがいいみたいですね。
StringBuilderの基本的なオペレーションには、appendメソッドおよびinsertメソッドがあり、これらのメソッドはどんな種類のデータも受け取ることができるようにオーバーロードされています。メソッドはそれぞれ与えられたデータを効率的に文字列に変換し、文字列中の文字を文字列ビルダーに追加または挿入します。appendメソッドは常に、ビルダーの末尾に与えられた文字を追加し、insertメソッドは指定された位置に文字を追加します。
たとえば、zを、現在「start」を含む文字列ビルダー・オブジェクトと見なす場合、z.append("le")は文字列ビルダーの内容が「startle」になるように変更するのに対して、z.insert(4, "le")というメソッド呼出しは文字列ビルダーの内容が「starlet」になるように作用します。
一般に、sbがStringBuilderのインスタンスを参照している場合、sb.append(x)はsb.insert(sb.length(), x)と同じ結果になります。
append
メソッドとinsert
メソッドが代表メソッドでappend
メソッドが末尾に文字列を追加しinsert
メソッドが引数で指定した位置に文字列を追加するみたいです。
プラス演算子との違い
可変であるStringBuilder
に対して固定であるString
は文字列を追加するたびにnew
されるらしいです。
この場合3回もnew
されるのでその分のメモリを消費します。それが原因で+
演算子での文字列結合は遅いみたいです。そう言われるとStringBuilder
を使わない手はないですね。
ここで初心者が一瞬混乱する例を見てみましょう。
この結果はどうなると思いますか?■■■■■■■■■■
が出力されると思いきや実は■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
こう表示されるんです。■
が55個並んでいます。いったいどういうことでしょうか?原因は3行目のStringBuilder sb = new StringBuilder();
です。for
文の外側でsb
変数を定義しているのでfor
文の実行内容が変数sb
の末尾に追加されていくわけです。ではfor
文の中に入れてみましょう。
これで結果は■■■■■■■■■■
となります。考えてみればなんでもないのですが2つ目のコードの変数sb
はfor
文の条件がtrue
であれば、その都度new
されるので変数sb
の中身がnull
になります。気をつけましょう。
メソッドを試す
append
メソッドで文字列を末尾にできます。これは簡単ですね。
insert
メソッドです。引数で指定した箇所に文字列を挿入します。
deleteCharAt
メソッドです。引数で指定した箇所の文字列を削除します。
便利なメソッドばかりなので文字列を扱うときはStringBuilder
は便利ですね。
用語
あとがき
簡単なプログラムのときはString
で書くと思いますがStringBuilder
には慣れておきたいです。