はじめに
2 つの Key をもつ Map を利用したい.
たしか, C++ には Pair があった. Java にはないの?
結論
ない.
じゃあどうするか?
自分で作成するしかない!
class Pair<F, S> {
public final F first;
public final S second;
Pair (F first, S second) {
this.first = first;
this.second = second;
}
}
しかし, これでは 2 つの Key をもつ Map としてうまく動作しない.
import java.util.Map;
import java.util.HashMap;
public class PairSample {
public static void main (String[] args) {
Map<Pair<Integer,Integer>, String> map = new HashMap<Pair<Integer,Integer>, String>();
Pair pair = new Pair (1,2);
Pair pair2 = new Pair (1,2);
map.put (pair, "a");
if (map.containsKey (pair2)) {
System.out.println ("equal");
}
else {
System.out.println ("not equal");
}
}
}
秘密は, equals と hashCode にあった.
同一性と同値性
2 つのオブジェクトが同じ時, それらは同一性をもつという. hashCode () メソッドで検証する.
2 つのオブジェクトが保持する属性が同じとき, それらは同値性をもつという. equals () メソッドで検証する.
equals, hashCode はともに Object 型のメソッド.
以下のページが図つきでわかりやすい.
Map で二つのオブジェクトが同値だと判断するときは, equals メソッドをも ちいている.なので, このメソッドをオーバーロードして独自定義する必要がある.
実装例
今回やりたいことは, 同値性の確認なので, hashCode はなくてもいい.
ドキュメントによると, Hashcode があったほうが, HashMap の性能が上がるらしい.
@Override
public boolean equals (Object obj) {
if (! (obj instanceof Pair))
return false;
Pair pair = (Pair) obj;
return (first.equals (pair.first) && second.equals (pair.second));
}
@Override
public int hashCode () {
return first.hashCode () ^ second.hashCode ();
}