読者です 読者をやめる 読者になる 読者になる

MapとSet


ミュータブルとイミュータブル

Scala のリスト(配列)には、不変である List と可変である Array がありました。
これと同様に、Map と Set にも不変オブジェクトと可変オブジェクトがライブラリとして提供されています。

Map と Set 不変オブジェクトと可変オブジェクトの実装が、クラス階層を分けて提供される形となっています。なのでクラス名は同じで提供されています。

Set

HashSetを例にすると、以下のパッケージ階層でそれぞれ可変オブジェクトと不変オブジェクトがあります。用途に応じてimportして使用します。

  • scala.collection.mutable.HashSet
  • scala.collection.immutable.HashSet
import scala.collection.mutable.HashSet

object Main extends Application {
  val s = new HashSet[String]
  s += "one"
  s += ("two", "three")
  println(s.contains("two")) //true
}

不変オブジェクトの場合は+=などのメソッドが使えません。

import scala.collection.immutable.HashSet

object Main extends Application {
  val s = HashSet("one","two","three")
  println(s.contains("two"))
}

可変オブジェクトと不変オブジェクトの+メソッドはそれぞれの動作が異なります。
以下のコードを不変オブジェクトと可変オブジェクトに対して実行した場合、

  val s = Set("one", "two")
  println(s + "three")
  println(s)

可変オブジェクトの場合、s の要素にthreeが追加されます。

Set(three, two, one)
Set(three, two, one)

一方不変オブジェクトの場合は、+メソッドにより新しいオブジェクトが作成されるため、元の s は変更されないことになります。

Set(one, two, three)
Set(one, two)

Map

Map に関しても同様に以下のパッケージ階層で不変と可変のものが提供されています。

  • scala.collection.mutable.HashMap
  • scala.collection.immutable.HashMap
import scala.collection.mutable.HashMap

object Main extends Application {
  val m = new HashMap[Int, String]
  m += 1 ->"one"
  m += 2->"two"
  m += 3->"three"
  println(m(2)) //two
}

不変オブジェクトの場合は

import scala.collection.immutable.HashMap

object Main extends Application {
  val m = HashMap(1 ->"one", 2->"two", 3->"three")
  println(m(2)) //two
}