我正在尝试为数据结构中的密钥存储多个值,因此我使用的是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));
并返回false。
注意:键值存储在多图中,因为当我放置某些内容时destinations.size()
会增加。当密钥为String
而不是double[]
时,也不会发生这种情况。< / p>
知道问题是什么吗?
编辑:非常感谢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;
}
}
现在我遇到了一个新问题。这就是我使用它的方式:
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,第二个返回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);
}
}
谢谢大家。
答案 0 :(得分:8)
您使用数组作为哈希键。这不会起作用 - Java不会覆盖hashCode
和equals
数组。 (Arrays
类提供了执行此操作的方法,但它不会对您有所帮助。)不可否认,我希望它可以在这种特定情况下工作,您使用完全相同的引用< / em>同时为put
和containsKey
...当我测试您的代码时,它会打印true
。您确定可以使用完全代码重现吗?
例如,虽然我希望它适用于您提供的代码,但我不会期望它能够正常工作:
// Logically equal array, but distinct objects
double[] key = (double[]) startingPoint.clone();
System.out.println(destinations.containsKey(key));
听起来你不应该在这里使用double[]
- 你应该创建一个Point
类,它有两个double
个变量,并覆盖equals
和{{ 1}}。
此外,由于二进制浮点算法的本质,在散列键中使用hashCode
值通常通常一个坏主意。即使使用上面的double
想法,这也会成为一个问题...如果你不需要实际进行任何算术(如果你只是复制值),那就应该没问题了,但要小心。
答案 1 :(得分: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