For a HashMap that maps from a custom class, how to make it so that two equivalent keys will map to say value?
I have a custom class, for example's sake let's say it's tuples without order.
public class UnorderedTuple {
Integer i1 = null; Integer i2 = null;
UnorderedTuple(Integer int1, Integer int2) { i1 = int1; i2 = int2; }
boolean equals(UnorderedTuple t) { return t.i1 == i1 && t.i2 == t2 || t.i2 == i1 && t.i1 == i2; }
}
Like I said, a dumb example. Now, let's say i have
Map<UnorderedTuple, Integer> m = ne开发者_Python百科w HashMap<UnorderedTuple, Integer>();
Ideally, I'd like this functionality:
UnorderedTuple ut1 = new UnorderedTuple(1,2);
UnorderedTuple ut2 = new UnorderedTuple(2,1);
m.put(ut1,2);
m.put(ut2,3);
System.out.println(m.get(ut1)==3); //ideally returns true
Is there something I need to implement or extend such that I can have this functionality? In the same way that if you use 2 different, but equal strings, or Integers, or whatever as a key it will map it properly, but if I implement this as written, it treats ut1 and ut2 separately. Even if I construct ut1 and ut2 identically, it does the same thing.
Thanks for your help.
You need to override hashCode()
... in this case you'd probably do it by XORing the hash codes of all the fields involved, to get the order-independence you want.
You also need to override equals(Object)
rather than just implementing equals(UnorderedTuple)
.
I also note that you're using "==" to compare instances of Integer
: don't do that. It will work in the test case you've given due to the rules around boxing, but if you try it with values over 127 you may well run into problems - it's only comparing references rather than values. Call equals
to compare values properly.
You need to implement hashCode()
in a way that is consistent with equals()
(in other words, if a.equals(b)
returns true
, then a.hashCode() == b.hashCode()
must be true
as well).
Chapter 3 of Effective Java (free PDF!) has all the nitty-gritty details!
Edit: an you also need to make sure that you're actually implementing equals(Object)
. In your sample code you only implement equals(UnorderedTuple)
, which is not the same!
Did you implement equals() and hashCode()? That could be the problem. Link to docs javadoc
Implement hashCode
You will have to define a custom hash function which would evaluate to the same value for both of the tuples. This however is a non-trivial as the hash function is important in determining the performance of the hashmap.
精彩评论