一.概述
Set是通过Map来支持的,Set接口里的所有方法,都委托给内部的Map去实现。
二.HashSet源码
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { static final long serialVersionUID = -5024744406713321676L; //内部保存一个map引用 private transient HashMap<E,Object> map; //此static final的Object来充当map的value private static final Object PRESENT = new Object(); //构造函数里面初始化一个map public HashSet() { map = new HashMap<E,Object>(); } public HashSet(Collection<? extends E> c) { map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<E,Object>(initialCapacity, loadFactor); } public HashSet(int initialCapacity) { map = new HashMap<E,Object>(initialCapacity); } //此构造函数不是public的 //它初始化了一个LinkedHashMap,可以猜到LinkedHashSet继承了HashSet //HashSet靠HashMap实现,LinkedHashSet靠LinkedHashMap实现,HashSet和LinkedHashSet提供一样的方法 //LinkedHashSet继承HashSet + 这里的构造函数 = LinkedHashSet只需要构造函数,不需要任何其它代码了 HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor); } //迭代Key public Iterator<E> iterator() { return map.keySet().iterator(); } public int size() { return map.size(); } public boolean isEmpty() { return map.isEmpty(); } //o就是map里面的key public boolean contains(Object o) { return map.containsKey(o); } //添加数据给map去实现就好了,返回boolean public boolean add(E e) { return map.put(e, PRESENT)==null; } //删除数据给map去实现就好了返回boolean public boolean remove(Object o) { return map.remove(o)==PRESENT; } public void clear() { map.clear(); } //clone出一个newSet,给此newSet的成员变量map赋值 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(); } } //依然是序列化map里面存放的对象 private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden serialization magic s.defaultWriteObject(); // Write out HashMap capacity and load factor s.writeInt(map.capacity()); s.writeFloat(map.loadFactor()); // Write out size s.writeInt(map.size()); // Write out all elements in the proper order. for (Iterator i=map.keySet().iterator(); i.hasNext(); ) s.writeObject(i.next()); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden serialization magic s.defaultReadObject(); // Read in HashMap capacity and load factor and create backing HashMap int capacity = s.readInt(); float loadFactor = s.readFloat(); map = (((HashSet)this) instanceof LinkedHashSet ? new LinkedHashMap<E,Object>(capacity, loadFactor) : new HashMap<E,Object>(capacity, loadFactor)); // Read in size int size = s.readInt(); // Read in all elements in the proper order. for (int i=0; i<size; i++) { E e = (E) s.readObject(); map.put(e, PRESENT); } }
三.LinkedHashSet源码
public class LinkedHashSet<E> extends HashSet<E> //extends HashSet implements Set<E>, Cloneable, java.io.Serializable { private static final long serialVersionUID = -2851667679971038690L; public LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); //dummy=true } public LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } public LinkedHashSet() { super(16, .75f, true); } public LinkedHashSet(Collection<? extends E> c) { super(Math.max(2*c.size(), 11), .75f, true); addAll(c); }
四.TreeSet源码
同HashSet一样的道理,就不贴代码了。
五.Set里面是否能存放null
不必刻意去记,把前几篇分析Map的文章搞清楚了,很自然就知道了。