HashCode可以理解为类似哈希码的一种整形值,跟内存地址有关系。在HashSet中,会根据HashCode分成多个区域去存储加进来的集合元素。
比如:HashCode为1的放在 A区域,HashCode 为2的放在B区域。那么当你去寻找集合中的某个元素时,可以根据HashCode值,先大致确定元素所在区域,提高了查找效率。HashSet是不能包含重复元素的,那么它是如何判断呢。
1.首先,它会调用元素的HashCode()方法,去判断是否相同。不同的话,表示这两个元素不是同一个,可以加入。
2.如果HashCode()方法返回值相同,那么它会调用equals()方法,如果返回值为true,那么表示这两个元素是同一个元素,加入失败。
见代码:
上面的代码中,因为重写了Demo类的hashCode和equals方法。hashCode返回值相同,equals方法返回为true。所以,虽然在hs集合中添加了两个Demo对象,可实际上第二个未加进去,hs.size()为1。因为 hs判断这两个元素相同。
同理如果注释掉hashCode()方法,同时加入System.out.println(hs.remove(new Demo("1")));这句话,即把上面的代码注释去掉。发现hs.size()为2,并没有把之前添加的new Demo("1")对象去掉。原因是hashCode调用remove方法时,判断该元素是否在集合中,也是通过上面所说的两点。当你吧hashCode()方法注释掉后,remove方法中的形参new Demo("1"),会重新创建一个对象,它在内存中的地址已经跟第一次加入的不同了,即两个对象的hashCode()返回值已经不同。所以是删不掉hs集合中的第一个元素的。
这也就是说,如果你重写了hashCode方法,而且它与对象的某一属性相关,那么当你把把该元素加入集合后,不能更改对象的该属性值,因为该对象的hashCode返回值已经变了,不能找到之前添加的该对象了。