2

キーの複数の値をデータ構造に格納しようとしているので、Guava(Googleコレクション)のMultiMapを使用しています。

Multimap<double[], double[]> destinations = HashMultimap.create();
destinations = ArrayListMultimap.create();

double[] startingPoint = new double[] {1.0, 2.0};
double[] end = new double[] {3.0, 4.0};
destinations.put(startingPoint, end);

System.out.println(destinations.containsKey(startingPoint));

そしてそれはfalseを返します。

destinations.size()注:キー値は、何かを配置すると増加するにつれてマルチマップに格納されます。また、キーが。Stringの代わりにある場合も発生しませんdouble[]

問題が何であるかについて何か考えはありますか?

編集:JonSkeetに感謝します。クラスを実装しました。

class Point {

    double lat;
    double lng;

    public boolean equals(Point p) {

        if (lat == p.lat && lng == p.lng)
            return true;
        else
            return false;
    }

    @Override
    public int hashCode() {

        int hash = 29;
        hash = hash*41 + (int)(lat * 100000);
        hash = hash*41 + (int)(lng * 100000);

        return hash;
    }

    public Point(double newlat, double newlng) {
        lat = newlat;
        lng = newlng;
    }
}

そして今、私は新しい問題を抱えています。これが私がそれを使用している方法です:

Multimap<Point, Point> destinations = HashMultimap.create();
destinations = ArrayListMultimap.create();

Point startingPoint = new Point(1.0, 2.0);
Point end = new Point(3.0, 4.0);
destinations.put(startingPoint, end);

System.out.println( destinations.containsKey(startingPoint) );
System.out.println( destinations.containsKey(new Point(1.0, 2.0)) );

最初のものはtrueを返し、2番目のものはfalseを返します。@Overrideメソッドの前に置くとエラーにequalsなりますが、現在の問題は何ですか?

ありがとう :)

equalsEdit2:これに変更すると、期待どおりに動作するようになりました。

@Override
public boolean equals(Object p) {

    if (this == p)
        return true;
    else if ( !(p instanceof Point) )
        return false;
    else {
        Point that = (Point) p;
        return (that.lat == lat) && (that.lng == lng);
    }
}

みんな、ありがとう。

4

2 に答える 2

8

ハッシュキーとして配列を使用しています。それは機能しません-JavaはオーバーライドせずhashCodeequals配列に対しても機能しません。(Arraysクラスはこれを行うメソッドを提供しますが、ここでは役に立ちません。)確かに、両方にまったく同じ参照を使用ているこの特定のケースでは機能すると思います...あなたのコード、それは印刷されます。正確にあなたのコードでそれを再現できると確信していますか?putcontainsKeytrue

たとえば、あなたが与えたコードではうまくいくと思いますが、これはうまくいくとは思いません:

// Logically equal array, but distinct objects
double[] key = (double[]) startingPoint.clone();
System.out.println(destinations.containsKey(key));

ここで実際に使用するべきではないように思えます.2つの変数を持つクラスをdouble[]作成し、 と をオーバーライドする必要があります。PointdoubleequalshashCode

さらに、doubleハッシュキーで値を使用することは、バイナリ浮動小数点演算の性質上、通常は悪い考えです。上記のアイデアを使用してもそれは問題になるでしょうPoint...実際に演算を行う必要がない場合(値をコピーするだけの場合)は問題ありませんが、細心の注意を払ってください...

于 2012-04-05T12:51:17.067 に答える
1

問題は、「等しい」配列をハッシュして毎回同じ結果を得ることができないことです。例えば:

public static void main(String[] args) {
     System.out.println(new double[]{1.0, 2.0}.hashCode());
     System.out.println(new double[]{1.0, 2.0}.hashCode());
}

のような結果になります

306344348
1211154977
于 2012-04-05T12:55:09.347 に答える