7

HashMap<Point, T>クラスの他のインスタンスにマップされるいくつかのポイントを保持するデータ構造がありますT。クラスが次のようにインスタンス化されると、このマップにはいくつかのデフォルト値が与えられます。

T t1 = new T();
T t2 = new T();
Point p1 = new Point(0, 1);
Point p2 = new Point(0, 2);

HashMap<Point, T> map = new HashMap<Point, T>();
static {
    map.put(p1, t1);
    map.put(p2, t2);
}

私のコードでは、xy値を含むイベントを受け取ります。これらのイベントのいずれかを受け取ると、渡されたandを使用して新しいPointオブジェクトを作成し、次のようにマップから値を取得しようとしています。xy

Point p = new Point(event.getX(), event.getY); // Assume (x, y) = (0, 1) (p1)
if(p.equals(p1)    
    T t = map.get(p);

この場合は (with (x, y) = (0, 1) とp等しいですが、から値を取得しています。これは、 のメソッドが固有のハッシュを計算する以外の何かを使用しているためだと思います。衝突を防ぐために。p1nullmaphashCode()Point (Point2D)equals

私の質問は、新しいインスタンスを使用して値を取得するにはどうすればよいですか? ユースケースに適合する別のデータ構造はありますか?mapp

または、目的に合わせてクラスとメソッドを拡張するtoString()などの他のマッピングを使用できると思います。これらの方法は「ハッキー」に感じますが、よりクリーンな方法があれば、ぜひ聞きたいです。HashMap<String, T>PointOverridehashCode()

4

4 に答える 4

6

Javaのドキュメントによると、

メソッドに従って 2 つのオブジェクトが等しい場合、2 つのオブジェクトのそれぞれでメソッドequals(Object)を呼び出すとhashCode、同じ整数の結果が生成される必要があります。

あなたの場合、2つのPointオブジェクトは(メソッドに従って)等しいようですequalsが、それらのハッシュコードは異なります。equalsこれは、関数とhashCode関数が互いに一貫性を保つように修正する必要があることを意味します。

于 2013-01-29T18:54:00.403 に答える
2

次のような自己完結型の例を書いてみてください。

Map<Point, String> map = new LinkedHashMap<>();
for (int i = 0; i < 10; i++)
    for (int j = 0; j < 10; j++)
        map.put(new Point(i, j), "(" + i + "," + j + ")");

// test the map
int misMatches = 0;
for (int i = 0; i < 10; i++)
    for (int j = 0; j < 10; j++) {
        String expected = "(" + i + "," + j + ")";
        String text = map.get(new Point(i, j));
        if (!expected.equals(text)) {
            System.err.println("Expected <" + expected + "> but got <" + text + ">");
            misMatches++;
        }
    }
System.out.println(misMatches + " mis-matches found.");

プリント

0 mis-matches found.
于 2013-01-29T18:59:53.933 に答える
2

Pointクラスのequals()またはhashcode()に問題はないと思います。これを試してください:

public static void main(String args[]) {

        Map<Point, Integer> map = new HashMap<Point, Integer>();
        Point p1 = new Point(0, 1);
        Point p2 = new Point(0, 2);
        map.put(p1,1);
        map.put(p2,2);
        Point p = new Point(0, 1);
        if(p.equals(p1)){
            System.out.println(map.get(p));
        }
        else{
            System.out.println("not");
        }



    }

正しい結果が得られています。

マップを適切に初期化していないと思います。

于 2013-01-29T19:15:27.033 に答える
1

hashCode()は、一貫性を保つために、equals()と同じ属性を使用する必要があります。

参照:JavaでequalsとhashCodeをオーバーライドする場合、どのような問題を考慮する必要がありますか?

于 2013-01-29T18:50:18.780 に答える