プログラムを書いていて、ハッシュテーブルの要素のソート(並べ替え)を行ってから要素を順に処理する必要がありました。
JavaのHashtableクラスは、ハッシュテーブルに格納した要素の順序は保持されません。まずは、JavaでSortedHashtableクラスを作ってみました。
import java.util.Collections; import java.util.Enumeration; import java.util.Hashtable; import java.util.Set; import java.util.TreeSet; import java.util.Vector; public class SortedHashtable extends Hashtable { public SortedHashtable(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); } public SortedHashtable(int initialCapacity) { super(initialCapacity); } public SortedHashtable() { super(); } public Enumeration keys() { Vector v = new Vector(super.keySet()); Collections.sort(v); return v.elements(); } public Set keySet() { TreeSet s = new TreeSet(super.keySet()); return s; } public Enumeration elements() { Enumeration e = super.elements(); Vector v = new Vector(); while (e.hasMoreElements()){ v.add(e.nextElement()); } Collections.sort(v); return v.elements(); } }
Javaのプログラムなので、SortedHashtableクラスはこれでいいのですが、これをScalaでクラス化したくなります。
Javaクラスを継承して、Scalaクラスで作ってみようと以下のコードを書いてみたのですが、
package Hello import java.util.Collections; import java.util.Enumeration; import java.util.Hashtable; import java.util.Set; import java.util.TreeSet; import java.util.Vector; class SortedHashtable[A,B](initialCapacity :Int, loadFactor:Float) extends java.util.Hashtable(initialCapacity, loadFactor) { def this() = this(11,0.75F) def this(initialCapacity: Int) = this(initialCapacity,0.75F) override def keys = { var v = new Vector(super.keySet()); Collections.sort(v) v.elements() } override def keySet = new TreeSet(super.keySet()); override def elements = { var e = super.elements(); var v = new Vector(); while (e.hasMoreElements()){ v.add(e.nextElement()) } Collections.sort(v) v.elements() } override def remove(key) = super.remove(key) override def put(key:A,value:B) = super.put(key,value) }
putのところで、Javaのput(key,values)の引数がNothing でないとダメだといってコンパイルできません。
次のように書けばコンパイルはできるのですが、
override def put(key,value) = super.put(key,value)
var h = new SortedHashtable[String,String] h.put("123","abc")
と書くと引数はNothingじゃないとダメとなります。
となると、override を外して、CASTするしかないかということで、以下のようにコードを修正します。
def put(key:A,value:B) = super.put(key.asInstanceOf[Nothing],value.asInstanceOf[Nothing])
これでコンパイルは通るのですが、今度は実行時エラー。確かにNothingですから。
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to scala.runtime.Nothing$ at Hello.SortedHashtable.put(SortedHashtable.scala:30) at Hello.testS0rtedHashtable$.main(testS0rtedHashtable.scala:6) at Hello.testS0rtedHashtable.main(testS0rtedHashtable.scala)
Nothing にはキャストできないといわれても。Anyになるといいのですが。
まだまだ勉強中です。
コメントを残す
コメントを投稿するにはログインしてください。