HashSet是一个Set,也就是所谓的集合。集合的概念是元素在集合中无序、唯一。HashSet,就是通过其中的元素(对象)的hashconde来区分对象是否唯一的。每次执行set.add(obj)的时候,都会取出obj的hashcode与其内部的hashcode list进行比较 。其obj也就是hashmap的key。hashmap的key是不能有重复的,所以 set中的元素是不能重复的,如果使用add(object obj)方法添加已经存在的对象,则会覆盖前面的对象。HashSet實作Set介面,Set介面繼承Collection介面,Set容器中的物件都是唯一的,加入 Set容器中的物件都必須重新定義equals()方法,作為唯一性的識別,Set容器有自己的一套排序規則。
HashSet的排序規則是利用Hash Table,所以加入HashSet容器的物件還必須重新定義hashCode()方法。
add方法:
public boolean add(E e)
- 如果此 set 中尚未包含指定元素,则添加指定元素。更确切地讲,如果此 set 没有包含满足 (e==null ? e2==null : e.equals(e2)) 的元素 e2,则向此 set 添加指定的元素 e。如果此 set 已包含该元素,则该调用不更改 set 并返回 false。
例:
1. import java.util.*;
2. class KeyMaster {
3. public int i;
4. public KeyMaster(int i) { this.i = i; }
5. public boolean equals(Object o) { return i == ((KeyMaster)o).i; }
6. public int hashCode() { return i; }
7. }
8. public class MapIt {
9. public static void main(String[] args) {
10. Set<KeyMaster> set = new HashSet<KeyMaster>();
11. KeyMaster k1 = new KeyMaster(1);
12. KeyMaster k2 = new KeyMaster(2);
13. set.add(k1); set.add(k1);
14. set.add(k2); set.add(k2);
15. System.out.print(set.size() + “:”);
16. k2.i = 1;
17. System.out.print(set.size() + “:”);
18. set.remove(k1);
19. System.out.print(set.size() + “:”);
20. set.remove(k2);
21. System.out.print(set.size());
22. }
23. }
What is the result?
A. 4:4:2:2
B. 4:4:3:2
C. 2:2:1:0
D. 2:2:0:0
E. 2:1:0:0
F. 2:2:1:1
G. 4:3:2:1
answer:F
k2的i变了之后,HashMap计算它的hashCode的时候会计算出跟k1一样的结果,而实际上k2根本不和k1在一个桶里。它在哪个桶是由你put进去的时候决定的。所以hashmap去k1的桶里当然找不到k2,所以删不掉。map可以直接通过key得到index,从第index取得这个值对象,实际上你修改完k2 之后map 会根据k2 现在的hashCode=1 来计算 index的值,得出来的index 和 k1 的index 相同!! 这样虽然在remove(k2) 实际上还是在remove(k1)!
总结:
在java的集合中,判断两个对象(set中的KEY)是否相等的规则是:
1,判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等,完毕
如果相等,转入2
2,判断两个对象用equals运算是否相等
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等
注意:重写equals的原因是默认equals是比较地址。