(基于JDK1.8源码分析)
一,Set接口
特点: 元素不允许重复(包括null)
源码分析:继承自Collection
public interface Set<E> extends Collection<E> { int size(); boolean isEmpty(); boolean contains(Object o); Iterator<E> iterator(); Object[] toArray(); <T> T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean retainAll(Collection<?> c); boolean removeAll(Collection<?> c); void clear(); boolean equals(Object o); int hashCode(); @Override default Spliterator<E> spliterator() { return Spliterators.spliterator(this, Spliterator.DISTINCT); } }
二,HashSet源码分析
【1】HashSet类实现
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
【2】底层实现
HashSet底层基于HashMap实现,其相关操作也是底层调用HashMap方法实现
HashSet元素无序,且顺序会发生改变
private transient HashMap<E,Object> map; //使用HashMap存储HashSet元素 // Dummy value to associate with an Object in the backing Map private static final Object PRESENT = new Object(); //使用空对象作为HashMap的Value
【3】构造方法
/** 初始化空的HashMap,初始容量16负载因子0.75*/ public HashSet() { map = new HashMap<>(); } /** 根据传入集合大小初始化空的HashMap, 并添加指定集合中元素*/ public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } /** 初始化一个指定容量和负载因子的HashMap */ public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } /** 初始化一个指定容量的HashMap */ public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } /** 初始化一个指定容量负载因子的链表哈希集合, 只限于包内访问*/ HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); }
【4】新增元素
/** 将指定元素添加到HashSet 1-未包含,直接添加 2-已包含,不更新元素返回false; 将元素作为HashMap的key进行存储,利用HashMap的key唯一性实现了Set元素的不重复性 */ public boolean add(E e) { return map.put(e, PRESENT)==null; }
【5】读取元素
/** 返回HashSet元素的迭代器; 利用HashMap的keySet返回所有key */ public Iterator<E> iterator() { return map.keySet().iterator(); }
【6】删除元素
/** 利用HashMap的remove操作记性Set元素删除 */ public boolean remove(Object o) { return map.remove(o)==PRESENT; }