Why doesn't my hashmap work? My object has the property that hashCode() equality implies equals(…) equality [closed]

江枫思渺然 提交于 2019-12-25 18:52:10

问题


Why doesn't my Java HashMap work? My object has the property that .equals equality implies hashCode equality.

You can assume that I'm modifying a field of the object after I add the object to the HashMap.


回答1:


You can assume that I'm modifying a field of the object after I add the object to the HashMap.

That right there is why.

Javadoc says:

Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map.

"Not specified" means "may not to work", so you should not be surprised when it doesn't work.




回答2:


If you're mutating (changing) the objects after you add them to the HashMap, your objects will be in the wrong bucket. This is because even though the object has changed, the object is not "refiled" into the (new) correct bucket after the changes occur.

Thus, methods like remove will fail to find your object, because the object is sitting in an outdated bucket.

What really drives this home (for me) is that when the object is initially added to the HashMap, the hash value (an int) is stored with the Entry. This implies that the hash is a relatively static property that is rarely (never) updated.

Possible work-arounds include:

  1. It'll probably work if you iterate through each Entry in the hashmap and create a new HashMap from those entries. This is probably bad in terms of performance but probably the most correct thing to do.

  2. Don't include the field that's changing in your hashCode function. While not great (taking advantage of unspecified compiler behavior is risky business, at best), it tends to work, because you'll just have collisions, which only affect performance, not correctness. You still need to include the problematic field in your .equals(Object obj) method, or else you can end up removing the wrong objects.

  3. Algorithmic solution: Find a way to store a different piece of data in the object that acts as the key that's constant. E.g., in my application, I was tracking the "age" of the object with an integer field. Every time I reached a certain amount of time in my application, I would go increment the age of all of the keys. If something was older than 50 units of time, then I could reasonably throw out the key-value pair. Alternatively, I could change the object to store the "birthtime" of the object. That is, if the application was 1000 time units old when the object was created, I'd store the number 1000. Then, to determine the age of the object, I could diff the current "time" against the birthtime and throw out the object if the difference was > 50.



来源:https://stackoverflow.com/questions/44560136/why-doesnt-my-hashmap-work-my-object-has-the-property-that-hashcode-equality

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!