java.util.TreeSet
类继承自 java.util.AbstractSet
抽象类,实现了 java.util.NavigableSet
、 java.lang.Cloneable
、 java.io.Serializable
接口。
一、TreeSet特点或规范 TreeSet
是基于 java.util.TreeMap
的 java.util.NavigableSet
实现类。
有序 :元素按照其自然顺序排序,或在创建时指定比较器,具体实现取决于创建时调用的的构造函数。
不可重复 。
1.1 时间复杂度 TreeSet 的基本操作(**add(Object)
、 remove(Object)
、 contains(Object)
**)均保证了时间复杂度为 **O(logN)**。
1.2 有序性保证 注意 :子类如果要正确实现 Set 接口,则由 Set 维护的排序(无论是否提供显式比较器)必须与 equals() 方法保持一致。 因为 Set 接口的唯一性是根据 equals()
方法决定的,而 TreeSet 是使用 compareTo()
方法实现元素比较。 TreeSet 实例即使排序与 equals() 方法不一致也是正确的,只是没有遵守 Set 接口规范。
1.3 线程不安全 注意 :TreeSet 类线程不同步 。 如果多个线程同时访问 TreeSet,并且至少有一个线程修改了该 Set,则必须在外部进行同步。 实现同步的方法最好在创建 TreeSet 时完成,以防止对集合的意外不同步访问:
1 SortedSet s = Collections.synchronizedSortedSet(new TreeSet (...));
1.4 并发迭代 如果在创建迭代器之后的任何时候修改了TreeSet,除了通过迭代器自己的 **remove()
**方法之外,迭代器将抛出 **ConcurrentModificationException
**。
二、成员变量 TreeSet 底层由 TreeMap 实现。
1 2 3 4 private transient NavigableMap<E,Object> m;private static final Object PRESENT = new Object ();
三、构造器 空参构造器(遵循 Collection 接口规范) 使用 TreeMap 实例,比较器为默认自然排序。
1 2 3 public TreeSet () { this (new TreeMap <E,Object>()); }
参数为 Collection 类型的构造器(遵循 Collection 接口规范) 使用 TreeMap 实例,比较器为默认自然排序。
1 2 3 4 public TreeSet (Collection<? extends E> c) { this (); addAll(c); }
参数为 Comparator 类型的构造器 使用 TreeMap 实例,自定义比较器。
1 2 3 public TreeSet (Comparator<? super E> comparator) { this (new TreeMap <>(comparator)); }
参数为 SortedSet 集合类型的构造器 使用 TreeSet 实例,使用参数 SortedSet 的比较器。
1 2 3 4 public TreeSet (SortedSet<E> s) { this (s.comparator()); addAll(s); }
参数为 NavigableMap 类型的构造器 包访问权限,指定特定可导航的 Map 构造 TreeSet,用于子类扩展。
1 2 3 TreeSet(NavigableMap<E,Object> m) { this .m = m; }
四、方法分析 4.1 继承自 Set 接口的方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public Iterator<E> iterator () { return m.navigableKeySet().iterator(); }public int size () { return m.size(); }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 void clear () { m.clear(); }public boolean addAll (Collection<? extends E> c) { 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); return true ; } } return super .addAll(c); }
4.2 继承自 SortedSet 接口的方法 获取第一个元素。
1 2 3 public E first () { return m.firstKey(); }
获取最后一个元素。
1 2 3 public E last () { return m.lastKey(); }
获取集合的比较器。
1 2 3 public Comparator<? super E> comparator() { return m.comparator(); }
4.3 继承自 NavigableSet 接口的方法 元素操作 返回 Set 中大于 指定元素的最小元素 ,如果没有这样的元素,则返回 **null
**。
1 2 3 public E higher (E e) { return m.higherKey(e); }
返回 Set 中小于 指定元素的最大元素 ,如果没有这样的元素,则返回 **null
**。
1 2 3 public E lower (E e) { return m.lowerKey(e); }
返回 Set 中大于等于 指定元素的最小元素 ,如果没有这样的元素,则返回 **null
**。
1 2 3 public E ceiling (E e) { return m.ceilingKey(e); }
返回 Set 中小于等于 指定元素的最大元素 ,如果没有这样的元素,则返回 **null
**。
1 2 3 public E floor (E e) { return m.floorKey(e); }
删除并返回第一个(最低)元素,如果 Set 为空,则返回 **null
**。
1 2 3 4 public E pollFirst () { Map.Entry<E,?> e = m.pollFirstEntry(); return (e == null ) ? null : e.getKey(); }
删除并返回最后一个(最高)元素,如果 Set 为空,则返回 **null
**。
1 2 3 4 public E pollLast () { Map.Entry<E,?> e = m.pollLastEntry(); return (e == null ) ? null : e.getKey(); }
子集操作 返回 Set 的部分视图,其元素 小于 (或 等于 ,如果 inclusive 为 true
) toElement 。
1 2 3 public NavigableSet<E> headSet (E toElement, boolean inclusive) { return new TreeSet <>(m.headMap(toElement, inclusive)); }
返回 Set 的部分视图,其返回的元素 小于toElement 。
1 2 3 public SortedSet<E> headSet (E toElement) { return headSet(toElement, false ); }
返回 Set 的部分视图,其元素 大于 (或 等于 ,如果 inclusive 为 true
) fromElement 。
1 2 3 public NavigableSet<E> tailSet (E fromElement, boolean inclusive) { return new TreeSet <>(m.tailMap(fromElement, inclusive)); }
返回 Set 的部分视图,其返回的元素 大于等于fromElement 。
1 2 3 public SortedSet<E> tailSet (E fromElement) { return tailSet(fromElement, true ); }
返回 Set 的部分视图,其元素范围从 fromElement 到 toElement 。如果 fromElement 和 toElement 相等,则返回的集合为空,除非 fromInclusive 和 toInclusive 都为 **true
**。
1 2 3 4 public NavigableSet<E> subSet (E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { return new TreeSet <>(m.subMap(fromElement, fromInclusive, toElement, toInclusive)); }
返回 Set 的部分视图,其元素范围从 fromElement(包括) 到 toElement(不包括) 。如果 fromElement 和 toElement 相等,则返回的集合为空。
1 2 3 public SortedSet<E> subSet (E fromElement, E toElement) { return subSet(fromElement, true , toElement, false ); }
倒序操作 返回 Set 中元素的 逆序 视图。降序集合由此集合支持,因此对集合的更改也将反映在降序集合中,反之亦然。 返回集合的顺序等同于 **Collections.reverseOrder(comparator())
**。表达式 s.descendingSet().descendingSet()
返回集合等效于原集合 s。
1 2 3 public NavigableSet<E> descendingSet () { return new TreeSet <>(m.descendingMap()); }
以 降序 返回此集合中元素的迭代器。
1 2 3 public Iterator<E> descendingIterator () { return m.descendingKeySet().iterator(); }
4.4 继承自 Collection 接口的方法 获得 TreeMap 中的分割器。
1 2 3 public Spliterator<E> spliterator () { return TreeMap.keySpliteratorFor(m); }
4.5 其他方法 复制当前集合。
1 2 3 4 5 6 7 8 9 10 public Object clone () { TreeSet<E> clone; try { clone = (TreeSet<E>) super .clone(); } catch (CloneNotSupportedException e) { throw new InternalError (e); } clone.m = new TreeMap <>(m); return clone; }
1 2 3 4 5 6 7 8 9 10 11 12 private void writeObject (java.io.ObjectOutputStream s) throws java.io.IOException { s.defaultWriteObject(); s.writeObject(m.comparator()); s.writeInt(m.size()); for (E e : m.keySet()) s.writeObject(e); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 private void readObject (java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); @SuppressWarnings("unchecked") Comparator<? super E> c = (Comparator<? super E>) s.readObject(); TreeMap<E,Object> tm = new TreeMap <>(c); m = tm; int size = s.readInt(); tm.readTreeSet(size, s, PRESENT); }