1. 概要

このチュートリアルでは、ScalaでStringBuilderクラスを使用する理由と方法を説明します。

2. 文字列の連結

多くの場合、コード内で2つ以上の文字列を結合する必要があります。 Scalaでは、これは通常、プラス(+)演算子を使用して行われます。

scala> val s = "abc"
val s: String = abc

scala> val res = s + "def"
val res: String = abcdef

しかし、前の例の内部で実際に何が起こっているかを見てみましょう。

最初に考えられたことがありますが、最初の文字列に文字を追加することはありません。 初期変数を見ると、値が不変に保たれていることがわかります。 同じことが2番目の変数にも当てはまります。

scala> val s = "abc"
val s: String = abc

scala> val other = "def"
val other: String = def

scala> val res = s + other
val res: String = abcdef

scala> println(s)
abc

scala> println(other)
def

これは、毎回両方の文字列の文字を使用して新しい文字列を作成しているためです。 文字列は変更できない不変オブジェクトです。

3. 文字列連結に関するパフォーマンスの問題

したがって、文字列を連結するたびに新しい文字列を作成しています。 これは何を意味するのでしょうか? 連結された文字列などの新しいオブジェクトを作成するには、この新しいオブジェクトにメモリを割り当てる必要があります。 通常、これは前の例のような単純なケースでは問題になりません。 しかし、時にはそれを考慮に入れる必要があります。

オブジェクトの巨大なSetを反復処理していて、反復処理するオブジェクトごとに、文字列表現を取得してアキュムレータ文字列に追加するとします。 セットが巨大な場合、これは多くの新しい文字列を割り当てていることを意味し、それぞれが前の文字列よりも大きくなっています。 反復の最後のステップでは、数千の文字を含む文字列を簡単に保持できます。

4. StringBuilder

ここで、StringBuilderが大いに役立ちます。 このクラスは、可変の String を表すために使用され、String連結を非常に効率的に実行するように最適化されています。 したがって、今見た前のソリューションの代わりにそれを使用する必要があります。

Scala StringBuilder クラスは、基本的にJavaのStringBuilderクラスの慣用的なラッパーであることを考慮してください。

scala> val sb = new StringBuilder("Example")
val sb: StringBuilder = Example

scala> val res = (sb ++= " of String Concatenation")
val res: sb.type = Example of String Concatenation

scala> println(res)
Example of String Concatenation

StringBuilder クラスには、他にもいくつかの便利なメソッドが含まれています。 それらのいくつかを見てみましょう。

4.1. キャラクターの追加

最初に見るのは、StringBuilderに文字を追加する方法です。 これは、別のStringを追加するために見たのと同様のアプローチを使用して実行できます。

scala> val sb = new StringBuilder("Exampl")
val sb: StringBuilder = Exampl

scala> sb += 'e'
val res7: sb.type = Example

scala> println(sb)
Example

文字列を追加する場合のように++= メソッドを使用する代わりに、文字を追加するために +=メソッドを使用していることに注意してください。

4.2. 他のオブジェクトの追加

他のオブジェクトを追加する必要がある場合は、代わりに.appendメソッドを使用する必要があります。 これは、数値やカスタムクラスなどの任意のオブジェクトで機能します。 数字の場合、これは次のようになります。

scala> val sb = new StringBuilder("Example: ")
val sb: StringBuilder = Example:

scala> sb.append(42)
val res14: StringBuilder = Example: 42

scala> println(sb)
Example: 42

また、カスタムケースクラスの場合、クラスインスタンスを既存のStringBuilderに追加するだけです。

scala> case class MyExample(val i: Int)
class MyExample

scala> val obj = MyExample(42)
val obj: MyExample = MyExample(42)

scala> val sb = new StringBuilder("Example: ")
val sb: StringBuilder = Example:

scala> sb.append(obj)
val res16: StringBuilder = Example: MyExample(42)

scala> println(sb)
Example: MyExample(42)

4.3. コンテンツのクリア

現在のStringBuilderの内容をクリアする必要がある場合は、 .clear メソッドを使用するだけで、これまでに追加されたすべての文字が削除されます。

scala> println(sb)
Example: MyExample(42)

scala> println(sb)
Example: MyExample(42)

scala> sb.clear()

scala> println(sb) //empty String will be printed


scala> sb.append(42)
val res21: StringBuilder = 42

scala> println(sb)
42

4.4. 文字の削除

このクラスでは、 .delete メソッドを使用して、開始インデックスと終了インデックスを指定することにより、文字のサブストリングを削除することもできます。

scala> val sb = new StringBuilder("Example")
val sb: StringBuilder = Example

scala> sb.delete(2,4)
val res24: StringBuilder = Exple

4.5. 文字列に変換しています

StringBuilderからStringに変換するには、.toStringメソッドを呼び出す必要があります。

scala> val sb = new StringBuilder("Example")
val sb: StringBuilder = Example

scala> sb.toString
val res25: String = Example

5. 結論

この記事では、StringBuilderを使用してScalaで文字列連結を行う方法を説明しました。 また、単純な連結操作を使用すると、複雑なケースで問題が発生する可能性がある理由もわかりました。