[Scala] HashMapを拡張する
今日はScalaのHashMapを拡張してみます。
多くのJavaプログラマが不満に思っていると思うのですが、Javaではほとんどのクラスがfinalで定義されていることもあり、既存のクラスを拡張することができませんでした。Scalaの良いところは、既存のライブラリも簡単に拡張できることです。
まず、HashMapを使ってみます。Symbolをキーとして、Intを値に持つHashMapを使ってみます。
scala> var hashMap1 = new HashMap[Symbol, Int] hashMap1: scala.collection.mutable.HashMap[Symbol,Int] = Map() scala> hashMap1.put('hoge, 1) res6: Option[Int] = None scala> hashMap1.put('foo, 2) res7: Option[Int] = None scala> hashMap1 res8: scala.collection.mutable.HashMap[Symbol,Int] = Map('hoge -> 1, 'foo -> 2) scala> hashMap1.contains('hoge) res9: Boolean = true scala> hashMap1.contains("hoge") <console>:7: error: type mismatch; found : java.lang.String("hoge") required: Symbol hashMap1.contains("hoge") ^
キーの型をSymbolとStringを間違えてしまいました。Stringでアクセスすると、型が異なるので、評価することができませんでした。StringとSymbolは相互にアクセスできてもいいですね。
ということで、StringでもSymbolでもアクセスできるStringAccessHashMapを作成してみます。
import scala.collection.mutable.HashMap class StringAccessHashMap[T] extends HashMap[Symbol,T] { def put(key: String, elem:T) : Option[T] = { super.put(Symbol(key), elem) } def contains(key : String) : Boolean = { super.contains(Symbol(key)) } def get(key : String): Option[T] = { super.get(Symbol(key)) } }
内容は簡単です。キーとしてSymbol型を持つHashMap型を継承し、Stringをキーとしてアクセスするインタフェースを追加しただけです。では実際に使ってみましょう。
scala> var hashMap = new StringAccessHashMap[Int] hashMap: StringAccessHashMap[Int] = Map() scala> hashMap.put("hoge", 10) res0: Option[Int] = None scala> hashMap.get("hoge") res1: Option[Int] = Some(10) scala> hashMap.get('hoge) res2: Option[Int] = Some(10) scala> hashMap.contains('hoge) res3: Boolean = true scala> hashMap res4: StringAccessHashMap[Int] = Map('hoge -> 10)
お、これは便利かもしれない。