TreeSet源码分析

来源:互联网 发布:腾讯社会工程数据库 编辑:程序博客网 时间:2024/04/28 22:19

前言

全文扫了一眼TreeSet,就像HashSet复用了HashMap一样,TreeSet也基本完全复用了TreeMap,对于TreeMap可以看我的TreeMap的分析
TreeMap源码分析

这里我们就简单的分析一下TreeSet

官方解释

基于 TreeMap 的 NavigableSet 实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。

此实现为基本操作(add、remove 和 contains)提供受保证的 log(n) 时间开销。

注意,此实现不是同步的。如果多个线程同时访问一个 TreeSet,而其中至少一个线程修改了该 set,那么它必须 外部同步。

TreeSet定义

public class TreeSet<E> extends AbstractSet<E>    implements NavigableSet<E>, Cloneable, java.io.Serializable

成员变量

    //TreeSet内部红黑树的数据结构    private transient NavigableMap<E,Object> m;     //和HashSet一样,这个就是value的虚值,所有TreeSet的数据都存在Map的Key中   private static final Object PRESENT = new Object();

构造函数

  //参数为指定树的构函  TreeSet(NavigableMap<E,Object> m) {        this.m = m;    }   //无参构函,内部数据结构直接用TreeMap    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来完成(因为还可以指定实现了NavigableSet的树来构造TreeSet),元素e作为key存在map中,这也就是为什么TreeSet中不能有重复元素,因为map的key不可以重复    public boolean add(E e) {        return m.put(e, PRESENT)==null;    }

删除操作

   //毫无悬念的依然使用了底层的map   public boolean remove(Object o) {        return m.remove(o)==PRESENT;    }

总结:分析到这里我们可以知道,TreeSet的源码其实底层大量复用了TreeMap,在TreeSet中添加元素其实就是在TreeMap中添加键值对,添加的元素作为key,value其实是毫无作用的,所以JavaJDK将value设置成一个固定值 private static final Object PRESENT = new Object();对TreeMap感兴趣的朋友,可以点击上面的链接来看我关于TreeMap的源码分析。

原创粉丝点击