高卒文系Scala vol.9 - SetとMap (各々のfilterの結果も見てみた)-


Scala本、3.4辺り。SetとMap、それぞれのイミュータブル・ミュータブルの紹介程度の内容です。



Javaを知っている人ならコードを見ただけで大体理解できる内容になっていると思います。

紹介だけでは寂しいので、filterメソッドの結果も確認してみました。


Set


import scala.collection.mutable.{Set => MutalbleSet}
var numbers1 = Set(1,2,3,4)
//val numbersSet = Set(1,2,3,4)
numbers1 += 5
println("imutable Set : " + numbers1.filter(_ % 2 == 0))
val numbers2 = MutalbleSet(1,2,3,4)
numbers2 += 5
println("mutable Set  : " + numbers2.filter(_ % 3 == 1))
imutable Set : Set(4, 2)
mutable Set  : ArrayBuffer(1, 4)

import文は、もっと先の章で出てきますが、めちゃくちゃ便利なので使ってみました。

Scalaのimport文は、上のコードのようにimportしたクラスやパッケージに別名をつける事ができます。

scala.collection.mutable.SetにMutalbleSetという別名をで扱えるようにしています。


ScalaのデフォルトのSet(import無しで使えるSet)は、イミュータブルです。


「numbers1 += 5」の箇所は、numbers1がイミュータブルなので「number1 = number1 + 5」と同じ意味。

なので、後から要素を追加したいSetを入れる変数は「var」で定義する必要があります。

コメントアウトしている方で変数定義するとコンパイルエラーが発生します。


「numbers2 += 5」の箇所は、numbers2がミュータブルなので「numbers2.+=(5)」と同じ意味。

「val」で変数定義していても、要素を追加する事ができます。


ミュータブルなSetだとfilterメソッドの結果型がArrayBufferになるんですね。


Map


import scala.collection.mutable.{Map => MutalbleMap}
val pairs1 = Map(1 -> "one", 2 -> "two", (3,"three"))
//pairs1 += ("4" -> "four")
println("imutable Map : " + pairs1.filter(.2.length == 3))
val pairs2 = MutalbleMap[String, String]()
pairs2 += ("1" -> "one")
pairs2 += ("2" -> "two")
pairs2 += ("3" -> "three")
//pairs2 += ("4", "four")
println("mutable Map  : " + pairs2.filter(.2.endsWith("e")))
imutable Map : Map(1 -> one, 2 -> two)
mutable Map  : ArrayBuffer((3,three), (1,one))

イミュータブルなMapはコンストラクタにTupleを渡して初期化します。

「(key -> value)」でも「(key, value)」でもTupleを生成している事に違いはないと思います。


ミュータブルなMapだと、「+=」メソッドにTuple2を渡す事でキーと値を追加できます。

イミュータブルなMapだと、もちろんコンパイルエラーになります。


コメントアウトしている「pairs2 += (“4”, “four”)」は、

意味的には「pairs2 += (“1” -> “one”)」とかと同じだと思ったんですが、コンパイルエラーが発生しました。


「error: type mismatch」とメッセージが吐かれたんですが原因は不明。

「(“4”, “four”)」と「 (“1” -> “one”)」では型が違うのか・・・


と思って試してみました。

println (("3" -> "three").getClass.getName)
println (("4", "four").getClass.getName)
scala.Tuple2
scala.Tuple2


・・・同じじゃん!!


なにが違うんでしょうか・・・。

何か違うとした場合、なぜイミュータブルのコンストラクタのパラメータに「(“4”, “four”)」を使うのはOKなんでしょうか・・・


ちなみにScala本では、「(“3” -> “three”)」を使った例のみ掲載していました。

慣習的に「(“3” -> “three”)」を使うのがベターなんでしょう。


でも、気になる・・・・

Tupleがapplyメソッドで生成されるか、「->」メソッドで生成されるかの違い?

ちなみにスタックトレースはこんなでした。

D:\Scala\workspace\Sample\src\sample\Sample8.scala:35: error: type mismatch;
found   : java.lang.String("4")
required: (String, String)
pairs2 += ("4", "four")

文字列(“4”)を代入しようとしてる?なんでそう解釈されるんだろう・・・?



ミュータブルなMapのfilterメソッドの結果型は、またしてもArrayBuffer。

イミュータブルなMapのfilterメソッドだと、Mapが返ってくるんですね。


なんか、ハマり要素な予感。

このエントリーをはてなブックマークに追加
comments powered by Disqus