剖析Java 集合框架⑨-Set

2021-01-09  本文已影响0人  李元霸抢貂蝉

Set概括

前面详细介绍了 ListMap 常用的实现类和源码,下面进入另一个常用的集合类型- Set。主要是存放不重复的元素集合

HashSet

望文生意,跟HashMap很像,确实是的,HashSet 组合了 HashMap,很多功能都是操作这个成员变量 HashMap实现的。

可以先了解前篇 HashMap

看下成员变量:

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    static final long serialVersionUID = -5024744406713321676L;
    // 底层是使用HashMap 实现的
    private transient HashMap<E,Object> map;

    // HashMap里面 所有的value 存放的就是这个空的object
    private static final Object PRESENT = new Object();

下面再来看看构造方法:

   public HashSet() {
        map = new HashMap<>();
    }

    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }

    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

    // LlinkedHashSet 会调用改构造方法
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

可以看到,很简单的代码,就是实例化HashMap,而最后一个构造方法,我们发现不是publish的,实际是LinkedHashSet会调用的。
再来看看一下常用方法:

  // 添加方法
   public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
 
  // 删除方法
    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

  // 是否包含
  public boolean contains(Object o) {
        return map.containsKey(o);
    }

可以看到实际都是调用的 HashMap 的方法。

LinkedHashSet

有了 HashSet的分析经验,再来看 LinkedHashSet 轻而易举。底层就是 LinkedHashMap

可以先了解 LinkedHashMap

public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    private static final long serialVersionUID = -2851667679971038690L;

    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 直接继承了 HashSet,所以 super 调用的 HashSet的构造方法。

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

HashSet 一样,核心方法都是调用的 map 这个成员变量的方法。

TreeSet

支持排序,无重复的 集合。和 HashSet 一样,底层也是直接使用 map 实现。

可以先了解 TreeMap

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
   // TreeMap实现了NavigableMap
    private transient NavigableMap<E,Object> m;

    // 使用map时 存放的value
    private static final Object PRESENT = new Object();

    TreeSet(NavigableMap<E,Object> m) {
        this.m = m;
    }

    public TreeSet() {
        this(new TreeMap<E,Object>());
    }

    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

    public TreeSet(Collection<? extends E> c) {
        this();
        addAll(c);
    }

    public TreeSet(SortedSet<E> s) {
        this(s.comparator());
        addAll(s);
    }

无需额外加注解,很简单的代码。底层就是调用TreeMap来操作。基于 NavigableMap也能做一些导航,比如倒叙等操作。

总结

Set 是存放一堆不重复元素的集合,底层都是对应 Map 实现的。

量变引发质变,经常进步一点点,期待蜕变的自己。

上一篇 下一篇

猜你喜欢

热点阅读