Changing values in HashSet

妖精的绣舞 提交于 2019-11-30 05:24:31

You are facing the problem because the keys in your hashset are not immutable. If you don't have immutable keys, you will lose the reference of the original key object once modified. And will never be able to get handle of that, which is sometimes referred as memory leaks in collection. So if you use immutable keys, you wouldn't run into this situation.

As the question you linked to details, and as others have pointed out, you're encountering the mutable key issue. I'll requote from the Javadoc:

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

As you pointed out, you get that. The question is, how do you actually remove the object given that's the case? You can't use Set.remove(), because your object is lost in the hash table. You can, however, use an Iterator to do it. Something like the following:

TestClass toRemove = <the same instance, but mutated>;
for (Iterator<TestClass> iter = set.iterator(); iter.hasNext(); ) {
  TestClass item = iter.next();
  if (toRemove.equals(item)) {
    iter.remove();
  }
}

This approach relies on the fact that standard equals() methods, like you're using, have an instance check, and that check will return true.

Please keep in mind this is not the right way to solve this problem. The right way is to either use an immutable key or "exercise great care", but it is a way to remove a mutated object from a HashSet.

When you add testElement to the HashSet, it selects a bucket based on the hash code for testElement. When you ask the HashSet if it contains a TestElement, it computes the hash code of the object that it's looking for and searches only in that bucket.

As your hashCode() is based on non-final field, the hash code can change behind the scenes of the HashSet. Thus completely invalidating the basic assumption of the HashSet.

A correct implementation for the Testclass would have the s1 field as final.

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