简介

TreeSet 底层是采用TreeMap实现的一种Set, 所以它是有序的,同样也是非线程安全的

继承关系

image.png

源码解析

经过前面我们学习HashSet和LinkedHashSet,基本上已经掌握了Set实现的套路了

  1. package java.util;
  2. // TreeSet实现了NavigableSet接口,所以它是有序的
  3. public class TreeSet<E> extends AbstractSet<E>
  4. implements NavigableSet<E>, Cloneable, java.io.Serializable
  5. {
  6. // 元素存储在NavigableMap中
  7. // 注意它不一定就是TreeMap
  8. private transient NavigableMap<E,Object> m;
  9. // 虚拟元素, 用来作为value存储在map中
  10. private static final Object PRESENT = new Object();
  11. // 直接使用传进来的NavigableMap存储元素
  12. // 这里不是深拷贝,如果外面的map有增删元素也会反映到这里
  13. // 而且, 这个方法不是public的, 说明只能给同包使用
  14. TreeSet(NavigableMap<E,Object> m) {
  15. this.m = m;
  16. }
  17. // 使用TreeMap初始化
  18. public TreeSet() {
  19. this(new TreeMap<E,Object>());
  20. }
  21. // 使用带comparator的TreeMap初始化
  22. public TreeSet(Comparator<? super E> comparator) {
  23. this(new TreeMap<>(comparator));
  24. }
  25. // 将集合c中的所有元素添加的TreeSet中
  26. public TreeSet(Collection<? extends E> c) {
  27. this();
  28. addAll(c);
  29. }
  30. // 将SortedSet中的所有元素添加到TreeSet中
  31. public TreeSet(SortedSet<E> s) {
  32. this(s.comparator());
  33. addAll(s);
  34. }
  35. // 迭代器
  36. public Iterator<E> iterator() {
  37. return m.navigableKeySet().iterator();
  38. }
  39. // 逆序迭代器
  40. public Iterator<E> descendingIterator() {
  41. return m.descendingKeySet().iterator();
  42. }
  43. // 以逆序返回一个新的TreeSet
  44. public NavigableSet<E> descendingSet() {
  45. return new TreeSet<>(m.descendingMap());
  46. }
  47. // 元素个数
  48. public int size() {
  49. return m.size();
  50. }
  51. // 判断是否为空
  52. public boolean isEmpty() {
  53. return m.isEmpty();
  54. }
  55. // 判断是否包含某元素
  56. public boolean contains(Object o) {
  57. return m.containsKey(o);
  58. }
  59. // 添加元素, 调用map的put()方法, value为PRESENT
  60. public boolean add(E e) {
  61. return m.put(e, PRESENT)==null;
  62. }
  63. // 删除元素
  64. public boolean remove(Object o) {
  65. return m.remove(o)==PRESENT;
  66. }
  67. // 清空所有元素
  68. public void clear() {
  69. m.clear();
  70. }
  71. // 添加集合c中的所有元素
  72. public boolean addAll(Collection<? extends E> c) {
  73. // 满足一定条件时直接调用TreeMap的addAllForTreeSet()方法添加元素
  74. if (m.size()==0 && c.size() > 0 &&
  75. c instanceof SortedSet &&
  76. m instanceof TreeMap) {
  77. SortedSet<? extends E> set = (SortedSet<? extends E>) c;
  78. TreeMap<E,Object> map = (TreeMap<E, Object>) m;
  79. Comparator<?> cc = set.comparator();
  80. Comparator<? super E> mc = map.comparator();
  81. if (cc==mc || (cc != null && cc.equals(mc))) {
  82. map.addAllForTreeSet(set, PRESENT);
  83. return true;
  84. }
  85. }
  86. // 不满足上述条件, 调用父类的addAll()通过遍历的方式一个一个地添加元素
  87. return super.addAll(c);
  88. }
  89. // 子set(NavigableSet中的方法)
  90. public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
  91. E toElement, boolean toInclusive) {
  92. return new TreeSet<>(m.subMap(fromElement, fromInclusive,
  93. toElement, toInclusive));
  94. }
  95. // 头set(NavigableSet中的方法)
  96. public NavigableSet<E> headSet(E toElement, boolean inclusive) {
  97. return new TreeSet<>(m.headMap(toElement, inclusive));
  98. }
  99. // 尾set(NavigableSet中的方法)
  100. public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
  101. return new TreeSet<>(m.tailMap(fromElement, inclusive));
  102. }
  103. // 子set(SortedSet接口中的方法)
  104. public SortedSet<E> subSet(E fromElement, E toElement) {
  105. return subSet(fromElement, true, toElement, false);
  106. }
  107. // 头set(SortedSet接口中的方法)
  108. public SortedSet<E> headSet(E toElement) {
  109. return headSet(toElement, false);
  110. }
  111. // 尾set(SortedSet接口中的方法)
  112. public SortedSet<E> tailSet(E fromElement) {
  113. return tailSet(fromElement, true);
  114. }
  115. // 比较器
  116. public Comparator<? super E> comparator() {
  117. return m.comparator();
  118. }
  119. // 返回最小的元素
  120. public E first() {
  121. return m.firstKey();
  122. }
  123. // 返回最大的元素
  124. public E last() {
  125. return m.lastKey();
  126. }
  127. // 返回小于e的最大的元素
  128. public E lower(E e) {
  129. return m.lowerKey(e);
  130. }
  131. // 返回小于等于e的最大的元素
  132. public E floor(E e) {
  133. return m.floorKey(e);
  134. }
  135. // 返回大于等于e的最小的元素
  136. public E ceiling(E e) {
  137. return m.ceilingKey(e);
  138. }
  139. // 返回大于e的最小的元素
  140. public E higher(E e) {
  141. return m.higherKey(e);
  142. }
  143. // 弹出最小的元素
  144. public E pollFirst() {
  145. Map.Entry<E,?> e = m.pollFirstEntry();
  146. return (e == null) ? null : e.getKey();
  147. }
  148. public E pollLast() {
  149. Map.Entry<E,?> e = m.pollLastEntry();
  150. return (e == null) ? null : e.getKey();
  151. }
  152. // 克隆方法
  153. @SuppressWarnings("unchecked")
  154. public Object clone() {
  155. TreeSet<E> clone;
  156. try {
  157. clone = (TreeSet<E>) super.clone();
  158. } catch (CloneNotSupportedException e) {
  159. throw new InternalError(e);
  160. }
  161. clone.m = new TreeMap<>(m);
  162. return clone;
  163. }
  164. // 序列化写出方法
  165. private void writeObject(java.io.ObjectOutputStream s)
  166. throws java.io.IOException {
  167. // Write out any hidden stuff
  168. s.defaultWriteObject();
  169. // Write out Comparator
  170. s.writeObject(m.comparator());
  171. // Write out size
  172. s.writeInt(m.size());
  173. // Write out all elements in the proper order.
  174. for (E e : m.keySet())
  175. s.writeObject(e);
  176. }
  177. // 序列化写入方法
  178. private void readObject(java.io.ObjectInputStream s)
  179. throws java.io.IOException, ClassNotFoundException {
  180. // Read in any hidden stuff
  181. s.defaultReadObject();
  182. // Read in Comparator
  183. @SuppressWarnings("unchecked")
  184. Comparator<? super E> c = (Comparator<? super E>) s.readObject();
  185. // Create backing TreeMap
  186. TreeMap<E,Object> tm = new TreeMap<>(c);
  187. m = tm;
  188. // Read in size
  189. int size = s.readInt();
  190. tm.readTreeSet(size, s, PRESENT);
  191. }
  192. // 可分割的迭代器
  193. public Spliterator<E> spliterator() {
  194. return TreeMap.keySpliteratorFor(m);
  195. }
  196. // 序列化id
  197. private static final long serialVersionUID = -2479143000061671589L;
  198. }

源码比较简单,基本都是调用map 相应的方法。

总结

(1)TreeSet底层使用NavigableMap存储元素;
(2)TreeSet是有序的;
(3)TreeSet是非线程安全的;
(4)TreeSet实现了NavigableSet接口,而NavigableSet继承自SortedSet接口;
(5)TreeSet实现了SortedSet接口