1、hashset 不重复的集合,类似于数学中的集
2、内部结构 基于hashmap,使用key唯一性,value值可以重复的特性;
private transient HashMap map;
//value都是一个值 private static final Object PRESENT = new Object(); public HashSet() { map = new HashMap(); }
//添加一个元素的时候,调用hashmap的添加对象
public boolean add(Object obj) { return map.put(obj, PRESENT) == null; } public Object put(Object obj, Object obj1) { return putVal(hash(obj), obj, obj1, false, true); }
//这个部分是jdk1.8的添加的方法 推荐下面的博客看实现原理
//http://blog.csdn.net/qq_27093465/article/details/70314904
public Object put(Object obj, Object obj1) { return putVal(hash(obj), obj, obj1, false, true); } final Object putVal(int i, Object obj, Object obj1, boolean flag, boolean flag1) { Node anode[]; int j; if((anode = table) == null || (j = anode.length) == 0) j = (anode = resize()).length; Object obj2; int k; if((obj2 = anode[k = j - 1 & i]) == null) { anode[k] = newNode(i, obj, obj1, null); } else { Object obj3; Object obj4; if(((Node) (obj2)).hash == i && ((obj4 = ((Node) (obj2)).key) == obj || obj != null && obj.equals(obj4))) obj3 = obj2; else if(obj2 instanceof TreeNode) { obj3 = ((TreeNode)obj2).putTreeVal(this, anode, i, obj, obj1); } else { int l = 0; do { if((obj3 = ((Node) (obj2)).next) == null) { obj2.next = newNode(i, obj, obj1, null); if(l >= 7) treeifyBin(anode, i); break; } Object obj5; if(((Node) (obj3)).hash == i && ((obj5 = ((Node) (obj3)).key) == obj || obj != null && obj.equals(obj5))) break; obj2 = obj3; l++; } while(true); } if(obj3 != null) { Object obj6 = ((Node) (obj3)).value; if(!flag || obj6 == null) obj3.value = obj1; afterNodeAccess(((Node) (obj3))); return obj6; } } modCount++; if(++size > threshold) resize(); afterNodeInsertion(flag1); return null; } // 获得hash的值 static final int hash(Object obj) { int i; return obj != null ? (i = obj.hashCode()) ^ i >>> 16 : 0; }
set集合遍历 也是调用hashmap中key值的方法
public Iterator iterator() { return map.keySet().iterator(); } public boolean contains(Object obj) { return map.containsKey(obj); }
没有看源码的时都没有想到,hashset内部居然通过hashmap中key实现,