プログラミングいちねんせい

プログラミング初心者が優雅にもがく軌跡です

文字列を連結するなら演算子ではなくStringBuilderが推奨されるらしいです

文字の連結といえば+演算子を使ったおなじみの式でしたが、それよりもStringBuilderが推奨されているという噂を聞きつけました。というわけで今回もいろいろ見ていきます。

StringBuilderとは

文字の可変シーケンスです。このクラスは、StringBufferと互換性があるAPIを提供しますが、同期化は保証されません。このクラスは、文字列バッファが単一のスレッド(一般的なケース)により使用されていた場合のStringBufferの簡単な代替として使用されるよう設計されています。このクラスは、ほとんどの実装で高速に実行されるので、可能な場合は、StringBufferよりも優先して使用することをお薦めします。

今のところは文字列の連結は+演算子StringBuilderStringBufferの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つ目のコードの変数sbfor文の条件がtrueであれば、その都度newされるので変数sbの中身がnullになります。気をつけましょう。

メソッドを試す

appendメソッドで文字列を末尾にできます。これは簡単ですね。

insertメソッドです。引数で指定した箇所に文字列を挿入します。

deleteCharAtメソッドです。引数で指定した箇所の文字列を削除します。

便利なメソッドばかりなので文字列を扱うときはStringBuilderは便利ですね。

用語

  • シーケンス
    • 連続、順序
  • API
    • システムやプログラムに用意された拡張機能
  • バッファ
    • データを一時的に記憶する場所
  • スレッド
    • 処理をするCPUの単位

あとがき

簡単なプログラムのときはStringで書くと思いますがStringBuilderには慣れておきたいです。