Scala 例 Map
ScalaにもMapがある。
http://www.scala-lang.org/api/current/scala/collection/Map
これの動作を確認してみる
オブジェクトの生成と基本のメソッド
java.util.MapとScalaのMapのメソッドの対応は、以下のようだ
java.util.Map | scala.collection.Map | 説明 |
put | + | |
putAll | ++ | |
get | () | |
なし | get | Option型で返す |
なし | getOrElse | |
remove | - |
ただし、もとのMapオブジェクトは変化しない。もとのMapオブジェクトから、新しい別のMapオブジェクトが生成される。なにせ、immutableのパッケージゆえ。
scala> val map = Map(1 -> "a", 2 -> "b", 3 -> "c") map: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 2 -> b, 3 -> c) scala> map + (4 -> "d") res6: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 2 -> b, 3 -> c, 4 -> d) scala> map res7: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 2 -> b, 3 -> c) scala> map - (2) res8: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 3 -> c) scala> map res9: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 2 -> b, 3 -> c)
矢印 -> を何度もつかっている。これをつかうと、Tupleができるようだ。だから、4 -> "d"と(4, "d")は、Mapに+すると同じ結果になる
scala> 4 -> "d" res21: (Int, java.lang.String) = (4,d) scala> map + ((4, "d")) res23: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 2 -> b, 3 -> c, 4 -> d)
ScalaのMapのgetメソッドがある。
しかし、java.utilMapのgetとは、ちょっとちがう。
Optionというオブジェクトにつつまれた状態で、値を取得する。
scala> map.get(3) res25: Option[java.lang.String] = Some(c)
さらに、Optionオブジェクトからgetすると中身がとりだせる。
scala> map.get(3).get res27: java.lang.String = c
java.util.Mapのgetのように、そのままの値を取り出すためには、()を使う。デフォルト値を指定できるgetもある。
scala> map(2) res13: java.lang.String = b scala> map.getOrElse(3, "z") res10: java.lang.String = c scala> map.getOrElse(5, "z") res11: java.lang.String = z
Scalaの流儀としては、getをつかって、Option型でとりだすのが良いお作法のらしい。
また、java.util.Mapは、java.util.Iterableを継承してなかったけれど、
ScalaのMapは、scala.collection.Iterableを継承しているので、イテレートもばっちり
scala> map.foreach {println} (1,a) (2,b) (3,c)
Javaだと、Mapのままじゃだめで、entrySetメソッドで、Map.EntryのSetに変換して、イテレートさせてた。
import java.util.HashMap; import java.util.Map; public class LoopExample { public static void main(String[] args) { Map<Integer, String> map = new HashMap<Integer, String>(); map.put(1, "a"); map.put(2, "b"); map.put(3, "c"); for (Map.Entry<Integer, String> e : map.entrySet()) { Integer key = e.getKey(); String value = e.getValue(); } } }
ふう、Javaだと、こういう小さいサンプルについては、特に、めんどうくささを感じる。
scala.collection.mutable.HashMap
ScalaのMapのように、新しいMapを生成するのでなくて、java.util.Mapのように、自分自身の中身を変化させるMapが使いたい場合は、
http://www.scala-lang.org/api/current/scala/collection/mutable/HashMap
がある。