I’m trying to store multiple values for a key in a data structure so I’m using Guava (Google Collection)’s 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));
and it returns false.
Note: Key-values are being stored in the multimap as the destinations.size() increases when I put something there.It also does not happen when keys are String instead of double[].
Any idea what the problem is?
Edit: Many thanks to Jon Skeet I now implemented the class:
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;
}
}
And now I have a new problem. This is how I’m using it:
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)) );
The first one returns true, the second one returns false. It gives me an error if I put @Override before the equals method.Any Idea what the problem is now?
Thanks 🙂
Edit2: It now behaves exactly as expected when I changed equals to this:
@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);
}
}
Thanks everyone.
You’re using arrays as the hash keys. That’s not going to work – Java doesn’t override
hashCodeandequalsfor arrays. (TheArraysclass provides methods to do this, but it’s not going to help you here.) Admittedly I’d expect it to work in this specific case, where you’re using the exact same reference for bothputandcontainsKey… When I test your code, it printstrue. Are you sure you can reproduce it with exactly your code?For example, while I’d expect it to work for the code you’ve given, I wouldn’t expect this to work:
It sounds like you shouldn’t really be using
double[]here – you should create aPointclass which has twodoublevariables, and overridesequalsandhashCode.Additionally, using
doublevalues in hash keys is usually a bad idea anyway, due to the nature of binary floating point arithmetic. That’s going to be a problem even using thePointidea above… it should be okay if you don’t need to actually do any arithmetic (if you’re just copying values around) but take great care…