09 Dec 2014, 15:52

Java に Pair はないの?

はじめに

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 ();
}

Special Thanks