TreeMap是底层基于TreeMap的NavigableSet实现,容器的元素存储在TreeMap键值对映射的key中,它使用元素的天然顺序或者传入的比较器Comparator对元素进行排序。它为基本操做例如add、remove、contain提供了log(n)的时间复杂度保证。注意TreeSet不是线程同步的容器,若是有多个线程同时访问它,且至少有一个线程修改了容器的结构,那么他必须在外部进行同步处理。通常都是经过对天然封装该Set实例的对象进行同步操做来完成,若是没有这样的对象,那么可使用Collections.synChronizedSortedSet包装TreeSet为一个线程安全的容器。java
该TreeSet容器返回的迭代器是快速失败的(fail-fast),即在生成迭代器以后,若是该容器发生告终构部性修改除了经过迭代iterator.remove方法删除元素以外,迭代器将会抛出ConcurrentModificationException异常,该异常并不能绝对保证,应该只用于检测异常。安全
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable { /** 内部TreeMap实例 **/ private transient NavigableMap<E,Object> m; //静态对象充当TreeMap实例中的键值对中的value,全部key的value都是该对象 private static final Object PRESENT = new Object(); }
TreeSet继承自AbstractSet,AbstractSet提供了Set的一些基本方法实现,大大减小实现TreeSet的工做量,此外它实现了NavigableSet接口,扩展了倒序、获取给定目标最接近匹配等功能,实现了Clonable支持克隆、java.io.Serializable支持序列化数据结构
/** * 构造方法,指定NavigableMap实例 */ TreeSet(NavigableMap<E,Object> m) { this.m = m; } /** * 无参构造方法,默认建立一个TreeMap实例 */ public TreeSet() { this(new TreeMap<E,Object>()); } /** * 构造方法,建立一个空的TreeMap实例并按照方法指定的比较器对元素进行排序 */ public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); } /** * 构造方法,建立一个空的TreeSet实例,并将方法指定集合c的全部元素填充到TreeSet实例中 */ public TreeSet(Collection<? extends E> c) { this(); addAll(c); } /** * 构造方法,建立一个空的TreeSet实例,比较器取方法参数SortedSet对象的s的内部比较器, * 将容器s中的全部元素填充到内部TreeMap实例 */ public TreeSet(SortedSet<E> s) { this(s.comparator()); addAll(s); }
经过对TreeSet构造函数的分析,咱们能够了解到TreeSet的底层与HashSet相似,只不过它的底层存储结构是一个NavagableMap实例,通常是TreeMap对象,全部TreeSet的操做最终都是反映到底层对TreeMap的操做。函数
/** * 返回一个遍历当前容器元素的迭代器 */ public Iterator<E> iterator() { return m.navigableKeySet().iterator(); } /** * 判断当前容器是否为空 */ public boolean isEmpty() { return m.isEmpty(); } /** * 返回当前容器是否包含指定元素 */ public boolean contains(Object o) { return m.containsKey(o); } /** * 添加元素 */ public boolean add(E e) { return m.put(e, PRESENT)==null; } /** * 删除元素 */ public boolean remove(Object o) { return m.remove(o)==PRESENT; } /** * 获取容器第一个元素 */ public E first() { return m.firstKey(); } /** * 获取容器最后一个元素 */ public E last() { return m.lastKey(); }
经过对TreeSet成员方法的分析,咱们能够发现它们的实现彻底依赖于底层的NavigableMap实例(通常状况下能够简单视为TreeMap实例),容器元素对应的是TreeMap实例键值对的Key,若想研读底层实现能够直接去研读TreeMap响应方法的源码。源码分析