java 集合系列目录:
Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例
Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例
Java 集合系列 05 Vector详细介绍(源码解析)和使用示例
Java 集合系列 06 Stack详细介绍(源码解析)和使用示例
Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)
Java 集合系列 09 HashMap详细介绍(源码解析)和使用示例
Java 集合系列 10 Hashtable详细介绍(源码解析)和使用示例
Java 集合系列 11 hashmap 和 hashtable 的区别
概述
第1 部分 TreeSet介绍
TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。它继承于AbstractSet抽象类,实现了NavigableSet<E>, Cloneable, java.io.Serializable接口。
TreeSet 继承于AbstractSet,所以它是一个Set集合,具有Set的属性和方法。
TreeSet 实现了NavigableSet接口,意味着它支持一系列的导航方法。比如查找与指定目标最匹配项。
TreeSet 实现了Cloneable接口,意味着它能被克隆。
TreeSet 实现了java.io.Serializable接口,意味着它支持序列化。
TreeSet是基于TreeMap实现的。TreeSet中的元素支持2种排序方式:自然排序 或者 根据创建TreeSet 时提供的 Comparator 进行排序。这取决于使用的构造方法。
TreeSet为基本操作(add、remove 和 contains)提供受保证的 log(n) 时间开销。
另外,TreeSet是非同步的。 它的iterator 方法返回的迭代器是fail-fast的。
在TreeSet中定义了如下几个变量
private transient NavigableMap<E,Object> m; //PRESENT会被当做Map的value与key构建成键值对 private static final Object PRESENT = new Object();
TreeSet的构造函数
// 默认构造函数。使用该构造函数,TreeSet中的元素按照自然排序进行排列。 TreeSet() // 创建的TreeSet包含collection TreeSet(Collection<? extends E> collection) // 指定TreeSet的比较器 TreeSet(Comparator<? super E> comparator) // 创建的TreeSet包含set TreeSet(SortedSet<E> set)
TreeSet的API
boolean add(E e) 将指定的元素添加到此 set(如果该元素尚未存在于 set 中)。 boolean addAll(Collection<? extends E> c) 将指定 collection 中的所有元素添加到此 set 中。 E ceiling(E e) 返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。 void clear() 移除此 set 中的所有元素。 Object clone() 返回 TreeSet 实例的浅表副本。 Comparator<? super E> comparator() 返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。 boolean contains(Object o) 如果此 set 包含指定的元素,则返回 true。 Iterator<E> descendingIterator() 返回在此 set 元素上按降序进行迭代的迭代器。 NavigableSet<E> descendingSet() 返回此 set 中所包含元素的逆序视图。 E first() 返回此 set 中当前第一个(最低)元素。 E floor(E e) 返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。 SortedSet<E> headSet(E toElement) 返回此 set 的部分视图,其元素严格小于 toElement。 NavigableSet<E> headSet(E toElement, boolean inclusive) 返回此 set 的部分视图,其元素小于(或等于,如果 inclusive 为 true)toElement。 E higher(E e) 返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 null。 boolean isEmpty() 如果此 set 不包含任何元素,则返回 true。 Iterator<E> iterator() 返回在此 set 中的元素上按升序进行迭代的迭代器。 E last() 返回此 set 中当前最后一个(最高)元素。 E lower(E e) 返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回 null。 E pollFirst() 获取并移除第一个(最低)元素;如果此 set 为空,则返回 null。 E pollLast() 获取并移除最后一个(最高)元素;如果此 set 为空,则返回 null。 boolean remove(Object o) 将指定的元素从 set 中移除(如果该元素存在于此 set 中)。 int size() 返回 set 中的元素数(set 的容量)。 NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) 返回此 set 的部分视图,其元素范围从 fromElement 到 toElement。 SortedSet<E> subSet(E fromElement, E toElement) 返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。 SortedSet<E> tailSet(E fromElement) 返回此 set 的部分视图,其元素大于等于 fromElement。 NavigableSet<E> tailSet(E fromElement, boolean inclusive) 返回此 set 的部分视图,其元素大于(或等于,如果 inclusive 为 true)fromElement。
说明:
(01) TreeSet是有序的Set集合,因此支持add、remove、get等方法。
(02) 和NavigableSet一样,TreeSet的导航方法大致可以区分为两类,一类是提供元素项的导航方法,返回某个元素;另一类时提供集合的导航方法,返回某个集合。
lower、floor、ceiling 和 higher 分别返回小于、小于等于、大于等于、大于给定元素的元素,如果不存在这样的元素,则返回 null。
第2 部分 TreeSet数据结构
TreeSet的继承关系
java.lang.Object ↳ java.util.AbstractCollection<E> ↳ java.util.AbstractSet<E> ↳ java.util.TreeSet<E> public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable{}
TreeSet与Collection关系如下图:
从图中可以看出:
(01) TreeSet继承于AbstractSet,并且实现了NavigableSet接口。
(02) TreeSet的本质是一个"有序的,并且没有重复元素"的集合,它是通过TreeMap实现的。TreeSet中含有一个"NavigableMap类型的成员变量"m,而m实际上是"TreeMap的实例"。
第3 部分 TreeSet 源码分析
1 package java.util; 2 3 4 public class TreeSet<E> extends AbstractSet<E> 5 implements NavigableSet<E>, Cloneable, java.io.Serializable 6 { 7 // NavigableMap对象 8 private transient NavigableMap<E,Object> m; 9 10 // TreeSet是通过TreeMap实现的, 11 // PRESENT是键-值对中的值。 12 private static final Object PRESENT = new Object(); 13 14 // 将TreeMap赋值给 "NavigableMap对象m" 15 TreeSet(NavigableMap<E,Object> m) { 16 this.m = m; 17 } 18 19 // 不带参数的构造函数。创建一个空的TreeMap 20 public TreeSet() { 21 this(new TreeMap<E,Object>()); 22 } 23 24 // 带比较器的构造函数。 25 public TreeSet(Comparator<? super E> comparator) { 26 this(new TreeMap<>(comparator)); 27 } 28 29 // 创建TreeSet,并将集合c中的全部元素都添加到TreeSet中 30 public TreeSet(Collection<? extends E> c) { 31 this(); 32 // 将集合c中的元素全部添加到TreeSet中 33 addAll(c); 34 } 35 36 // 创建TreeSet,并将s中的全部元素都添加到TreeSet中 37 public TreeSet(SortedSet<E> s) { 38 this(s.comparator()); 39 addAll(s); 40 } 41 42 // 返回TreeSet的顺序排列的迭代器。 43 // 因为TreeSet时TreeMap实现的,所以这里实际上时返回TreeMap的“键集”对应的迭代器 44 public Iterator<E> iterator() { 45 return m.navigableKeySet().iterator(); 46 } 47 48 // 返回TreeSet的逆序排列的迭代器。 49 // 因为TreeSet时TreeMap实现的,所以这里实际上时返回TreeMap的“键集”对应的迭代器 50 public Iterator<E> descendingIterator() { 51 return m.descendingKeySet().iterator(); 52 } 53 54 /** 55 * @since 1.6 56 */ 57 public NavigableSet<E> descendingSet() { 58 return new TreeSet<>(m.descendingMap()); 59 } 60 61 // 返回TreeSet的大小 62 public int size() { 63 return m.size(); 64 } 65 66 // 返回TreeSet是否为空 67 public boolean isEmpty() { 68 return m.isEmpty(); 69 } 70 71 // 返回TreeSet是否包含对象(o) 72 public boolean contains(Object o) { 73 return m.containsKey(o); 74 } 75 76 // 添加e到TreeSet中 77 public boolean add(E e) { 78 return m.put(e, PRESENT)==null; 79 } 80 81 // 删除TreeSet中的对象o 82 public boolean remove(Object o) { 83 return m.remove(o)==PRESENT; 84 } 85 86 // 清空TreeSet 87 public void clear() { 88 m.clear(); 89 } 90 91 // 将集合c中的全部元素添加到TreeSet中 92 public boolean addAll(Collection<? extends E> c) { 93 // Use linear-time version if applicable 94 if (m.size()==0 && c.size() > 0 && 95 c instanceof SortedSet && 96 m instanceof TreeMap) { 97 SortedSet<? extends E> set = (SortedSet<? extends E>) c; 98 TreeMap<E,Object> map = (TreeMap<E, Object>) m; 99 Comparator<? super E> cc = (Comparator<? super E>) set.comparator(); 100 Comparator<? super E> mc = map.comparator(); 101 if (cc==mc || (cc != null && cc.equals(mc))) { 102 map.addAllForTreeSet(set, PRESENT); 103 return true; 104 } 105 } 106 return super.addAll(c); 107 } 108 109 // 返回子Set,实际上是通过TreeMap的subMap()实现的。 110 public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, 111 E toElement, boolean toInclusive) { 112 return new TreeSet<>(m.subMap(fromElement, fromInclusive, 113 toElement, toInclusive)); 114 } 115 116 // 返回Set的头部,范围是:从头部到toElement。 117 // inclusive是是否包含toElement的标志 118 public NavigableSet<E> headSet(E toElement, boolean inclusive) { 119 return new TreeSet<>(m.headMap(toElement, inclusive)); 120 } 121 122 // 返回Set的尾部,范围是:从fromElement到结尾。 123 // inclusive是是否包含fromElement的标志 124 public NavigableSet<E> tailSet(E fromElement, boolean inclusive) { 125 return new TreeSet<>(m.tailMap(fromElement, inclusive)); 126 } 127 128 // 返回子Set。范围是:从fromElement(包括)到toElement(不包括)。 129 public SortedSet<E> subSet(E fromElement, E toElement) { 130 return subSet(fromElement, true, toElement, false); 131 } 132 133 // 返回Set的头部,范围是:从头部到toElement(不包括)。 134 public SortedSet<E> headSet(E toElement) { 135 return headSet(toElement, false); 136 } 137 138 // 返回Set的尾部,范围是:从fromElement到结尾(不包括)。 139 public SortedSet<E> tailSet(E fromElement) { 140 return tailSet(fromElement, true); 141 } 142 143 // 返回Set的比较器 144 public Comparator<? super E> comparator() { 145 return m.comparator(); 146 } 147 148 // 返回Set的第一个元素 149 public E first() { 150 return m.firstKey(); 151 } 152 153 // 返回Set的最后一个元素 154 public E last() { 155 return m.lastKey(); 156 } 157 158 // NavigableSet API methods 159 160 // 返回Set中小于e的最大元素 161 public E lower(E e) { 162 return m.lowerKey(e); 163 } 164 165 // 返回Set中小于/等于e的最大元素 166 public E floor(E e) { 167 return m.floorKey(e); 168 } 169 170 // 返回Set中大于/等于e的最小元素 171 public E ceiling(E e) { 172 return m.ceilingKey(e); 173 } 174 175 // 返回Set中大于e的最小元素 176 public E higher(E e) { 177 return m.higherKey(e); 178 } 179 180 // 获取第一个元素,并将该元素从TreeMap中删除。 181 public E pollFirst() { 182 Map.Entry<E,?> e = m.pollFirstEntry(); 183 return (e == null) ? null : e.getKey(); 184 } 185 186 // 获取最后一个元素,并将该元素从TreeMap中删除。 187 public E pollLast() { 188 Map.Entry<E,?> e = m.pollLastEntry(); 189 return (e == null) ? null : e.getKey(); 190 } 191 192 // 克隆一个TreeSet,并返回Object对象 193 public Object clone() { 194 TreeSet<E> clone = null; 195 try { 196 clone = (TreeSet<E>) super.clone(); 197 } catch (CloneNotSupportedException e) { 198 throw new InternalError(); 199 } 200 201 clone.m = new TreeMap<>(m); 202 return clone; 203 } 204 205 // java.io.Serializable的写入函数 206 // 将TreeSet的“比较器、容量,所有的元素值”都写入到输出流中 207 private void writeObject(java.io.ObjectOutputStream s) 208 throws java.io.IOException { 209 // Write out any hidden stuff 210 s.defaultWriteObject(); 211 212 // Write out Comparator 213 s.writeObject(m.comparator()); 214 215 // Write out size 216 s.writeInt(m.size()); 217 218 // Write out all elements in the proper order. 219 for (E e : m.keySet()) 220 s.writeObject(e); 221 } 222 223 // java.io.Serializable的读取函数:根据写入方式读出 224 // 先将TreeSet的“比较器、容量、所有的元素值”依次读出 225 private void readObject(java.io.ObjectInputStream s) 226 throws java.io.IOException, ClassNotFoundException { 227 // Read in any hidden stuff 228 s.defaultReadObject(); 229 230 // Read in Comparator 231 Comparator<? super E> c = (Comparator<? super E>) s.readObject(); 232 233 // Create backing TreeMap 234 TreeMap<E,Object> tm; 235 if (c==null) 236 tm = new TreeMap<>(); 237 else 238 tm = new TreeMap<>(c); 239 m = tm; 240 241 // Read in size 242 int size = s.readInt(); 243 244 tm.readTreeSet(size, s, PRESENT); 245 } 246 247 private static final long serialVersionUID = -2479143000061671589L; 248 }
总结:
(01) TreeSet实际上是TreeMap实现的。当我们构造TreeSet时;若使用不带参数的构造函数,则TreeSet的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带比较器的参数。
(02) TreeSet是非线程安全的。
(03) TreeSet实现java.io.Serializable的方式。当写入到输出流时,依次写入“比较器、容量、全部元素”;当读出输入流时,再依次读取。