HashSet 实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证Set的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null 元素。
HashSet 为基本操作提供了稳定性能,这些基本操作包括 add、remove、contains 和size,假定哈希函数将这些元素正确地分布在桶中。对此 set 进行迭代所需的时间与HashSet 实例的大小(元素的数量)和底层HashMap 实例(桶的数量)的“容量”的和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)
注意:HasetSet不是线程安全的。
//继承了AbstractSet抽象类,实现了Set接口,在HashMap基础上实现了Set的操作,源码比较简单 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { //内部存储结构,通过HashMap来存储,Set集合的值作为Map的键,Map的值为一个对象,其实值根本不重要 private transient HashMap<E,Object> map; //用来填充HashMap的值对象 private static final Object PRESENT = new Object(); //创建空的Set,Map对应的初始化为:装载因子为0.75,容量为16 public HashSet() { map = new HashMap<>(); } //添加集合的值 public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));//创建Map addAll(c);//添加元素 } //按容量和装载因子创建 public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } //装载因子为0.75 public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } //内部结构为LinkedHashMap,这个是提供给LinkedHashSet用的,不是给HashSet使用的 HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } //返回迭代器 public Iterator<E> iterator() { return map.keySet().iterator(); } //返回容量 public int size() { return map.size(); } //判断是否为空 public boolean isEmpty() { return map.isEmpty(); } //是否包含元素o public boolean contains(Object o) { return map.containsKey(o); } //添加元素 public boolean add(E e) { return map.put(e, PRESENT)==null;//添加元素,键为e,值为PRESENT } //删除元素 public boolean remove(Object o) { return map.remove(o)==PRESENT; } //清除所有元素 public void clear() { map.clear(); } //浅复制 public Object clone() { try { HashSet<E> newSet = (HashSet<E>) super.clone(); newSet.map = (HashMap<E, Object>) map.clone(); return newSet; } catch (CloneNotSupportedException e) { throw new InternalError(); } } }
JDK源码阅读之HashSet,布布扣,bubuko.com
原文:http://blog.csdn.net/lcli2009/article/details/22397697