Java MultiMap无法识别密钥

Tri*_*ing 2 java hashmap multimap

我正在尝试为数据结构中的密钥存储多个值,因此我使用的是Guava(Google Collection)的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));
Run Code Online (Sandbox Code Playgroud)

它返回false.

注意:destinations.size()当我把东西放在那里时,键值会存储在multimap Stringdouble[].当键代替时,也不会发生.

知道问题是什么吗?

编辑:非常感谢Jon Skeet我现在实现了这个类:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我遇到了一个新问题.这就是我使用它的方式:

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)) );
Run Code Online (Sandbox Code Playgroud)

第一个返回true,第二个返回false.如果我把方法放在方法@Override之前,它会给我一个错误equals.任何想法现在的问题是什么?

谢谢 :)

Edit2:当我改为equals这个时,它现在的行为完全符合预期:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

感谢大家.

Jon*_*eet 8

您正在使用数组作为哈希键.这不会起作用 - Java不会覆盖hashCodeequals数组.(本Arrays类提供的方法来做到这一点,但它不会帮助你在这里.)诚然,我希望它在这个特定的情况下,您使用的地方工作的完全相同的参考两个putcontainsKey......当我测试你的代码,打印出来true.你确定你可以重现它正是你的代码?

例如,虽然我希望它适用于您提供的代码,但我希望这样做:

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

听起来你不应该double[]在这里使用- 你应该创建一个Point有两个double变量的类,并覆盖equalshashCode.

此外,由于二进制浮点算法的本质,double在散列键中使用值通常是一个坏主意.即使使用Point上面的想法,这也会成为一个问题...如果你不需要实际进行任何算术(如果你只是复制值),那应该没问题,但要小心......