Java容器之TreeSet源码解析

Posted dragonets

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java容器之TreeSet源码解析相关的知识,希望对你有一定的参考价值。

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
package java.util;
 
public class TreeSet<E> extends AbstractSet<E>
  implements NavigableSet<E>, Cloneable, java.io.Serializable
{
  // NavigableMap对象
  private transient NavigableMap<E,Object> m;
 
  // TreeSet是通过TreeMap实现的,
  // PRESENT是键-值对中的值。
  private static final Object PRESENT = new Object();
 
  // 不带参数的构造函数。创建一个空的TreeMap
  public TreeSet() {
    this(new TreeMap<E,Object>());
  }
 
  // 将TreeMap赋值给 "NavigableMap对象m"
  TreeSet(NavigableMap<E,Object> m) {
    this.m = m;
  }
 
  // 带比较器的构造函数。
  public TreeSet(Comparator<? super E> comparator) {
    this(new TreeMap<E,Object>(comparator));
  }
 
  // 创建TreeSet,并将集合c中的全部元素都添加到TreeSet中
  public TreeSet(Collection<? extends E> c) {
    this();
    // 将集合c中的元素全部添加到TreeSet中
    addAll(c);
  }
 
  // 创建TreeSet,并将s中的全部元素都添加到TreeSet中
  public TreeSet(SortedSet<E> s) {
    this(s.comparator());
    addAll(s);
  }
 
  // 返回TreeSet的顺序排列的迭代器。
  // 因为TreeSet时TreeMap实现的,所以这里实际上时返回TreeMap的“键集”对应的迭代器
  public Iterator<E> iterator() {
    return m.navigableKeySet().iterator();
  }
 
  // 返回TreeSet的逆序排列的迭代器。
  // 因为TreeSet时TreeMap实现的,所以这里实际上时返回TreeMap的“键集”对应的迭代器
  public Iterator<E> descendingIterator() {
    return m.descendingKeySet().iterator();
  }
 
  // 返回TreeSet的大小
  public int size() {
    return m.size();
  }
 
  // 返回TreeSet是否为空
  public boolean isEmpty() {
    return m.isEmpty();
  }
 
  // 返回TreeSet是否包含对象(o)
  public boolean contains(Object o) {
    return m.containsKey(o);
  }
 
  // 添加e到TreeSet中
  public boolean add(E e) {
    return m.put(e, PRESENT)==null;
  }
 
  // 删除TreeSet中的对象o
  public boolean remove(Object o) {
    return m.remove(o)==PRESENT;
  }
 
  // 清空TreeSet
  public void clear() {
    m.clear();
  }
 
  // 将集合c中的全部元素添加到TreeSet中
  public boolean addAll(Collection<? extends E> c) {
    // Use linear-time version if applicable
    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<? super E> cc = (Comparator<? super E>) 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);
  }
 
  // 返回子Set,实际上是通过TreeMap的subMap()实现的。
  public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
                 E toElement,  boolean toInclusive) {
    return new TreeSet<E>(m.subMap(fromElement, fromInclusive,
                    toElement,  toInclusive));
  }
 
  // 返回Set的头部,范围是:从头部到toElement。
  // inclusive是是否包含toElement的标志
  public NavigableSet<E> headSet(E toElement, boolean inclusive) {
    return new TreeSet<E>(m.headMap(toElement, inclusive));
  }
 
  // 返回Set的尾部,范围是:从fromElement到结尾。
  // inclusive是是否包含fromElement的标志
  public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
    return new TreeSet<E>(m.tailMap(fromElement, inclusive));
  }
 
  // 返回子Set。范围是:从fromElement(包括)到toElement(不包括)。
  public SortedSet<E> subSet(E fromElement, E toElement) {
    return subSet(fromElement, true, toElement, false);
  }
 
  // 返回Set的头部,范围是:从头部到toElement(不包括)。
  public SortedSet<E> headSet(E toElement) {
    return headSet(toElement, false);
  }
 
  // 返回Set的尾部,范围是:从fromElement到结尾(不包括)。
  public SortedSet<E> tailSet(E fromElement) {
    return tailSet(fromElement, true);
  }
 
  // 返回Set的比较器
  public Comparator<? super E> comparator() {
    return m.comparator();
  }
 
  // 返回Set的第一个元素
  public E first() {
    return m.firstKey();
  }
 
  // 返回Set的最后一个元素
  public E first() {
  public E last() {
    return m.lastKey();
  }
 
  // 返回Set中小于e的最大元素
  public E lower(E e) {
    return m.lowerKey(e);
  }
 
  // 返回Set中小于/等于e的最大元素
  public E floor(E e) {
    return m.floorKey(e);
  }
 
  // 返回Set中大于/等于e的最小元素
  public E ceiling(E e) {
    return m.ceilingKey(e);
  }
 
  // 返回Set中大于e的最小元素
  public E higher(E e) {
    return m.higherKey(e);
  }
 
  // 获取第一个元素,并将该元素从TreeMap中删除。
  public E pollFirst() {
    Map.Entry<E,?> e = m.pollFirstEntry();
    return (e == null)? null : e.getKey();
  }
 
  // 获取最后一个元素,并将该元素从TreeMap中删除。
  public E pollLast() {
    Map.Entry<E,?> e = m.pollLastEntry();
    return (e == null)? null : e.getKey();
  }
 
  // 克隆一个TreeSet,并返回Object对象
  public Object clone() {
    TreeSet<E> clone = null;
    try {
      clone = (TreeSet<E>) super.clone();
    } catch (CloneNotSupportedException e) {
      throw new InternalError();
    }
 
    clone.m = new TreeMap<E,Object>(m);
    return clone;
  }
 
  // java.io.Serializable的写入函数
  // 将TreeSet的“比较器、容量,所有的元素值”都写入到输出流中
  private void writeObject(java.io.ObjectOutputStream s)
    throws java.io.IOException {
    s.defaultWriteObject();
 
    // 写入比较器
    s.writeObject(m.comparator());
 
    // 写入容量
    s.writeInt(m.size());
 
    // 写入“TreeSet中的每一个元素”
    for (Iterator i=m.keySet().iterator(); i.hasNext(); )
      s.writeObject(i.next());
  }
 
  // java.io.Serializable的读取函数:根据写入方式读出
  // 先将TreeSet的“比较器、容量、所有的元素值”依次读出
  private void readObject(java.io.ObjectInputStream s)
    throws java.io.IOException, ClassNotFoundException {
    // Read in any hidden stuff
    s.defaultReadObject();
 
    // 从输入流中读取TreeSet的“比较器”
    Comparator<? super E> c = (Comparator<? super E>) s.readObject();
 
    TreeMap<E,Object> tm;
    if (c==null)
      tm = new TreeMap<E,Object>();
    else
      tm = new TreeMap<E,Object>(c);
    m = tm;
 
    // 从输入流中读取TreeSet的“容量”
    int size = s.readInt();
 
    // 从输入流中读取TreeSet的“全部元素”
    tm.readTreeSet(size, s, PRESENT);
  }
 
  // TreeSet的序列版本号
  private static final long serialVersionUID = -2479143000061671589L;
}

总结:

以上是关于Java容器之TreeSet源码解析的主要内容,如果未能解决你的问题,请参考以下文章

Java - TreeSet源码解析

java源码之TreeSet

java 17 - 6 TreeSet集合及其add()方法的源码解析

死磕 java集合之TreeSet源码分析

#yyds干货盘点# Map - TreeSet & TreeMap 源码解析

Java中的容器(集合)之HashMap源码解析