集合篇:Set—TreeSet源码解析

本文详细解析了TreeSet如何通过两种复用思路利用TreeMap的特性,实现元素排序与迭代功能。一种是直接调用TreeMap的简单方法,另一种是在TreeSet中定义接口规范,由TreeMap实现复杂逻辑。

1.整体架构

TreeSet的结构大致与HashSet相似,底层依旧使用组合的方式,组合基础类TreeMap。所以能够对key进行排序。迭代的时候能够按照key的排序顺序进行迭代。

2.源码解析

TreeSet复用TreeMap的两种思路,

复用思路1

这一思路与HashSet复用HashMap的思路相同,

private transient NavigableMap<E,Object> m;

// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

public boolean add(E e) {
    return m.put(e, PRESENT)==null;
}

这里并没有直接使用TreeMap,而是创建了一个NavigableMap对象(具体原因之后会说)。利用的同样是TreeMap中key唯一且具有顺序的特性。

复用思路2

TreeSet类的定义如下,

public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable

该类在定义过程中实现了NavigableSet接口。

TreeSet元素迭代过程中,实现迭代的思路,

// NavigableSet 接口,定义了迭代的一些规范,和一些取值的特殊方法
// TreeSet 实现了该方法,也就是说 TreeSet 本身已经定义了迭代的规范
public interface NavigableSet<E> extends SortedSet<E> {
    Iterator<E> iterator();
    E lower(E e);
}  
// m.navigableKeySet() 是 TreeMap 写了一个子类实现了 NavigableSet接口,实现了 TreeSet 定义的迭代规范
public Iterator<E> iterator() {
    return m.navigableKeySet().iterator();
}

TreeMap中NavigableSet接口的实现如下,
Image
TreeMap实现了TreeSet定义的各种NavigableSet接口的方法。这里复用TreeMap的思路是,TreeSet定义接口规范,但具体的实现靠的是TreeMap中相同的接口规范进行实现

总结

复用思路总结

TreeSet组合TreeMap的两种思路总结如下,

  1. TreeSet直接使用TreeMap的某些功能,包装成自身的API,如add方法。
  2. TreeSet定义好接口规范,让TreeMap去实现。

这两种思路都是TreeSet调用TreeMap,但是功能的实现关系完全相反。第一种是功能的定义和实现都在TreeMap中,TreeSet只需要简单调用即可。第二种是TreeSet将接口定义出来,让TreeMap去实现内部逻辑(TreeSet负责接口定义,TreeMap用于实现)。

使用这两种思路复用的原因,

  1. 像add这种简单方法,直接使用思路1,主要是add的实现没有复杂的逻辑,TreeSet自己实现起来比较简单。
  2. 思路2主要用于复杂场景(如迭代场景)。比如需要能从头迭代、取到第一个值、取最后一个值等复杂操作,此外TreeMap底层结构复杂。这时最好让TreeSet实现接口定义,TreeMap去实现功能。TreeMap对自身底层的复杂结构非常清楚,实现起来准确又简洁。

什么场景下使用TreeSet

一般需要保证元素唯一的同时对元素进行排序时使用TreeSet,使用时最好元素先实现Comparable接口,这样便于底层的TreeMap依据key进行排序。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值