那么有没有人告诉你Set本质是什么?
Map
上一回我们说完Queue,
没看过的老铁可以看看我整理的系列:光头佳的求职之旅
https://blog.csdn.net/u013351145/category_11030408.html
set是无序、不可重复的
主要方法基本和Colletion接口一致
/** * 返回当前集合的个数,如果超过2147483647 * (即Integer的最大值)后也只能返回这个数值) */ int size(); // 判断当前集合是否为空,如果为空就返回true boolean isEmpty(); // 判断当前集合是否包含输入参数对象 boolean contains(Object o); // 迭代器(至于迭代的时候的顺序,要看你当前的集合,例如List可以保证顺序) Iterator<E> iterator(); // 将集合转化为数组 Object[] toArray(); // 在集合中新增一个元素 boolean add(E e); // 删除一个元素,这里提供的方法有个坑,后面再提 boolean remove(Object o); // 判断当前集合是否包含另一个集合 boolean containsAll(Collection<?> c); // 在当前集合里新增输入的集合元素 boolean addAll(Collection<?> c); // 在当前集合里删除输入的集合元素 boolean removeAll(Collection<?> c); //此处和Collection接口由区别 Spliterator<E> spliterator() { return Spliterators.spliterator(this, Spliterator.DISTINCT); }
HashSet中的Hash是HashMao的Hash
下方为继承关系图
// 使用HashMap来存储HashSet的元素 private transient HashMap<E,Object> map; // HashMap中存储的value值 private static final Object PRESENT = new Object(); // 构造一个空的hashSet,实际会初始化一个空的HashMap public HashSet() { map = new HashMap<>(); } // 构造一个包含指定集合中元素的新集合 public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } // 以指定的initialCapacity和loadFactor构造一个空的HashSet。 public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); }
实际将将该元素作为key放入HashMap,Value为默认的PRESENT。
由于HashMap的put()方法添加key-value对时,当新放入HashMap的Entry中key与集合中原有Entry的key相同(hashCode()返回值相等,通过equals比较也返回true),
新添加的Entry的value会将覆盖原来Entry的value,但key不会有任何改变,
因此如果向HashSet中添加一个已经存在的元素时,新添加的集合元素将不会被放入HashMap中,
原来的元素也不会有任何改变,这也就满足了Set中元素不重复的特性。
public boolean add(E e) { return map.put(e, PRESENT)==null; } // 删除也是同样的原理 public boolean remove(Object o) { return map.remove(o)==PRESENT; }
HashSet中底层依靠HashMap实现,因此它的默认是加载因子(0.75),默认长度16,你可以认为HashSet就是一个value固定而key在变化的特殊HashMap。
下图为继承关系
LinkedHashSet是HashSet的子类,基本方法和HashSet区别不大,
唯一的不同点在于LinkedHashSet中用于存储值的实现LinkedHashMap,
而HashSet使用的是HashMap。
public LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); } public LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } public LinkedHashSet() { super(16, .75f, true); }
LinkedHashSet中用LinkedHashMap来实现存储值。