Collection容器家族(TreeSet源码详解)

一、在Collection集合体系中的位置及概述 

        TreeSet继承自AbstractSet抽象类,实现了NavigableSet、Serializable、Cloneable、RandomAccess接口。它的特点是存储元素唯一,无序(输入和输出无序)。 TreeSet默认情况下是基于TreeMap实现的,是对TreeMap的封装。默认情况下和TreeMap一样,采用元素的内部比较器Comparable的compareTo方法来比较元素的大小。如果不用内部比较器,就需要在外部传入一个Comparator的实现类来比较。由于TreeMap实现中采用红黑树实现,所以add,remove,contains方法的时间复杂度最坏情况下能保证log( n )。

二、成员变量

    // 存放元素的Map,必须是实现了NavigableMap接口的类
    private transient NavigableMap<E,Object> m;

    // Dummy value to associate with an Object in the backing Map
    // 一个虚拟值,用于添加元素到map中时,key为元素的值,value用此虚拟值代替
    private static final Object PRESENT = new Object();

三、构造方法

    // 自定义实现了NavigableMap接口的Map来作为实现
    TreeSet(NavigableMap<E,Object> m) {
        this.m = m;
    }

    // 默认构造方法用TreeMap来实现
    public TreeSet() {
        this(new TreeMap<E,Object>());
    }

    // 以定制排序方式创建一个新的 TreeMap,
    // 根据该 TreeSet 创建一个 TreeSet,
    // 使用该 TreeMap 的 key 来保存 Set 集合的元素
    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

    //使用参数集合的元素构造本集合
    public TreeSet(Collection<? extends E> c) {
        // 无参构造器创建一个TreeSet,底层以TreeMap保存集合元素
        this();
        // 向TreeSet中添加Collection集合c里的所有元素
        addAll(c);
    }

    public TreeSet(SortedSet<E> s) {
        // 调用带比较器参数的构造器创建衣蛾TreeSet,底层以TreeMap保存集合元素
        this(s.comparator());
        // 向TreeSet中添加SortedSet集合s里的所有元素
        addAll(s);
    }

其中涉及到addAll方法

    // 将参数集合中所有元素添加到本集合中
    public  boolean addAll(Collection<? extends E> c) {
        // Use linear-time version if applicable
        // 条件:本集合为空、参数集合有元素、参数集合是SortedSet类型、m是TreeMap类型
        if (m.size()==0 && c.size() > 0 &&
            c instanceof SortedSet &&
            m instanceof TreeMap) {
            SortedSet<? extends E> set = (SortedSet<? extends E>) c;
            TreeMap<E,Object> map = (TreeMap<E, Object>) m;
            Comparator<?> cc = set.comparator();    // 获取比较器
            Comparator<? super E> mc = map.comparator();    // 获取比较器
            if (cc==mc || (cc != null && cc.equals(mc))) {  // 如果本集合比较器和参数集合比较器相同
                map.addAllForTreeSet(set, PRESENT); // 使用TreeMap的addAllForTreeSet方法将参数集合所有元素添加到本集合
                return true;
            }
        }
        return super.addAll(c); // 不满足上诉条件,则调用AbstractCollection超类的addAll方法添加
    }

其中涉及到TreeMap的addAllForTreeSet方法,查看我之前的博客。

四、常用API

1.添加元素

    // 添加元素
    public boolean add(E e) {
        // 调用TreeMap的put方法添加
        return m.put(e, PRESENT)==null;
    }

    // 将参数集合中所有元素添加到本集合中
    public  boolean addAll(Collection<? extends E> c) {
        // Use linear-time version if applicable
        // 条件:本集合为空、参数集合有元素、参数集合是SortedSet类型、m是TreeMap类型
        if (m.size()==0 && c.size() > 0 &&
            c instanceof SortedSet &&
            m instanceof TreeMap) {
            SortedSet<? extends E> set = (SortedSet<? extends E>) c;
            TreeMap<E,Object> map = (TreeMap<E, Object>) m;
            Comparator<?> cc = set.comparator();    // 获取比较器
            Comparator<? super E> mc = map.comparator();    // 获取比较器
            if (cc==mc || (cc != null && cc.equals(mc))) {  // 如果本集合比较器和参数集合比较器相同
                map.addAllForTreeSet(set, PRESENT); // 使用TreeMap的addAllForTreeSet方法将参数集合所有元素添加到本集合
                return true;
            }
        }
        return super.addAll(c); // 不满足上诉条件,则调用AbstractCollection超类的addAll方法添加
    }

2.删除元素

    // 清空集合所有元素
    public void clear() {
        // 调用TreeMap方法清除
        m.clear();
    }

    // 移除参数元素
    public boolean remove(Object o) {
        // 调用TreeMap方法清除
        return m.remove(o)==PRESENT;
    }

3.遍历操作

    public Iterator<E> iterator() {
        // 调用TreeMap方法清除
        return m.navigableKeySet().iterator();
    }

五、总结

        TreeSet原码中方法比较少,原因是因为他是TreeMap的封装类对象。提的的就不在此赘述了。

posted @ 2018-11-08 18:55  小情绪Ango  阅读(144)  评论(0编辑  收藏  举报