HashSet showing more values [closed]

牧云@^-^@ 提交于 2019-12-25 07:54:40

问题


class KeyMaster {
  public int i;
  public KeyMaster(int i) { this.i = i; }
  public boolean equals(Object o) { return i == ((KeyMaster)o).i; }
  public int hashCode() { return i; }
}


public class MIt 
{
 public static void main(String[] args) {
  Set<KeyMaster> set = new HashSet<KeyMaster>();
  KeyMaster k1 = new KeyMaster(1);
  KeyMaster k2 = new KeyMaster(2);
  set.add(k1); 
  set.add(k1);
  set.add(k2); 
  set.add(k2);
  System.out.println(set.size()+":");

  k2.i = 1; // this is creating another object in HashSet
  set.remove(k1);
  System.out.println(set.size()+":");
  set.remove(k2);
  System.out.print(set.size());
}
}

I have added two object to the HashSet and have removed it, but in the last s.o.p I still have size 1. I agree I have updated the value of k2 but still I haven't added that to my set.


回答1:


Hashset uses hashing to store and retrieve the objects. When we add an object in hashmap, JVM looks for the hashcode implentation to decide where to put the object in memory. When we retrieve an object again hashcode is used to get the location of the object. If you change an object after inserting it into a hashmap, the updated object will have a different hashcode than the originally stored object. As in your case when you update k2.i=1, hashcode for k2 will now be different from original k2 object. So when you call remove with updated k2, JVM actually couldn't find the object and hence not able to delete. Thats the reason why you see the size as 1 in your last s.o.p




回答2:


From the Javadoc for HashSet.remove():

Removes the specified element from this set if it is present. More formally, removes an element e such that (o==null ? e==null : o.equals(e))

You have a line with a comment in your code that says:

k2.i = 1; // this is creating another object in HashSet

I'm not sure what you think is going on there, but it isn't that.

k2 is a reference to an object you've put in your HashSet. You just changed the value of i in that object, which you are using in the overridden equals() and hashcode() methods. This is a really bad thing to do when you're talking about anything that involves a hash and why you really shouldn't be using mutable objects as keys.

It literally can no longer be found.

HashSet.remove() returns a boolean - if you were to check that return value, you'd find that it was false.




回答3:


k2.i = 1; is not creating another object in HashSet, but it changes k2's hash code. This is why set.remove(k2); cannot find and remove k2. If you test set.remove(k2) return value you will see false which means that object was not removed.



来源:https://stackoverflow.com/questions/16370654/hashset-showing-more-values

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