Reputation: 954
I'm currently working on a TD game with a map editor. Now obviously, you can save and load these maps (or should be able to, at least).
Problem is: at some point I'm calling .get()
on a HashMap
. Unfortunately, the keys that should be the same (logic-wise) are not the same object (in terms of reference), and, according to my previous google research, overriding their .equals
method isn't sufficient, since they still return different hashes with .hashCode()
(I verified that, they DO return different hashes, while .equals
does return true).
(On a side note, that's rather confusing, since the javadoc of HashMap.get(key)
only states that they have to be equal)
More specifically, the HashMap
contains instances of a class Path
of mine as keys, and should return the corresponding list of enemies (= value).
short version of Path
(without getters etc.):
public class Path
{
private List<Tile> tiles = new ArrayList<>();
@Override
public boolean equals(Object obj) {
//code comparing the two paths
}
@Override
public int hashCode() {
//what I still need to implement. ATM, it returns super.hashCode()
}
}
public class Tile
{
private int x;
private int y;
//constructor
//overrides equals
//getters & some convenience methods
}
Now if two Paths are equal, I'd like them to return the same hash code, so that the HashMap
returns the correct list of enemies. (I'll make sure not two identical paths can be added).
Now my question:
Do you suggest
?
Note that I'd prefer to avoid changing the HashMap
to some other type of map, if that would even help solve the problem.
Upvotes: 0
Views: 1169
Reputation: 43651
You definitely do need to implement your hashCode
consistent with equals
. IDEs often do decent job generating hashCode
and equals
. Also consider Objects.equals(...)
and Objects.hash(...)
.
One warning about using Path
as keys in the HashMap
. You will have to make the class immutable to make it work reliably. Or at least make sure that hashCode
of the key does not change. Otherwise you may not able to get you data back even with the same or equal key.
Upvotes: 2
Reputation: 37584
The List
has a useful method which conveniently is also named list.hashCode()
. This will compute the hashCode of all the elements inside the list. So you also have to implement the hashCode for Tile
which probably consist of some primitive fields or such.
e.g.
@Override
public int hashCode() {
return tiles != null ? tiles.hashCode() : 0;
}
See the docs here
int hashCode()
Returns the hash code value for this list. The hash code of a list is defined to be the result of the following calculation:
int hashCode = 1;
for (E e : list)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
This ensures that
list1.equals(list2)
implies thatlist1.hashCode()==list2.hashCode()
for any two lists,list1
andlist2
, as required by the general contract ofObject.hashCode()
.
Upvotes: 1