HashSet是借助于HashMap的key不允许重复这个特性来实现的。HashMap是操作键值对,而HashSet是操作HashMap的key完成相关操作,TreeSet比HashSet加了排序的功能,那是不是TreeSet也因应该是通过操作TreeMap来实现的呢?
right!!
先把HashSet的链接发上来,一样的部分就不多解释了:
容器源码分析之HashSet(四)
1.TreeSet的继承结构
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
2.TreeSet的属性
private transient NavigableMap<E,Object> m;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
这样看起来其实TreeSet跟HashSet一样,区别是HashSet的Map成员是HashMap,而TreeSet的Map成员是NavigableMap接口,为什么是NavigableMap接口而不直接是TreeMap呢?
Effective Java之通过接口引用对象(五十二)
3. TreeSet的构造函数
//传map
TreeSet(NavigableMap<E,Object> m) {
this.m = m;
}
//默认
public TreeSet() {
this(new TreeMap<E,Object>());
}
//定制排序方式
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
//传集合
public TreeSet(Collection<? extends E> c) {
this();
addAll(c);
}
从上述可以看出,TreeSet的构造函数都是通过新建一个TreeMap作为实际存储Set元素的容器,所以TreeSet里绝大部分方法都是直接调用 TreeMap 的方法来实现的。
4. TreeSet的常用方法
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
public Iterator<E> iterator() {
return m.keySet().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();
}
这些方法和HashSet常用方法几乎一模一样