Java 集合:HashSet ,TreeSet 实现原理

由于 HashSet,TreeSet 主要是利用了 HashMap 和 TreeMap,所以首先可以参考:

  • Java 集合:HashMap(put方法的实现与哈希冲突)
  • Java 集合:TreeMap 的使用(不包括原理,仅仅是简单的使用 demo)

HashSet

HashSet 实现了 Set 接口,而 Set 接口是继承于 Collection 接口,所以可以认为 Set 接口是 List 接口的兄弟。

对于 Set 接口,如注释所说:

 * A collection that contains no duplicate elements.  More formally, sets
 * contain no pair of elements e1 and e2 such that
 * e1.equals(e2), and at most one null element.  As implied by
 * its name, this interface models the mathematical set abstraction.

所以说不重复,而且HashSet 底层使用的是 HashMap,所以也无序。 这两点是和 List 接口下的 ArrayList,LinkedList 等的一大区别。

我们知道,HashMap 是键值对的形式,HashSet 没有什么键值对的概念,那它内部具体又是怎么利用 HashMap 实现的呢?

其实就是 HashSet 用了一个空对象,如 private static final Object PRESENT = new Object

  • 用这个空对象来填充 HashMap 的 value 域
  • 用这个空对象来填充 HashMap 的 value 域
  • 用这个空对象来填充 HashMap 的 value 域

如下面的 add 方法:

private transient HashMap map;

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

所以从这里就可以看出:

  • 利用了 HashMap 实现。HashSet 的方法就是调用 HashMap 的对应的方法。
  • 用空对象来填充 HashMap 的 value 域

TreeSet

这里需要知道,平常我们所使用的 ArrayList,LinkedList 的元素是按照插入的时候的顺序排列的,而不是按照这个元素的大小之类的排序,假如我们需要有这个功能的话,那么 TreeSet 就派上用场了。

当创建一个 TreeSet 的时候:

private transient NavigableMap m;

public TreeSet() {
    this(new TreeMap());
}
TreeSet(NavigableMap m) {
    this.m = m;
}

可以看到,内部是使用了 TreeMap。

当 add(E e) 方法的时候:

private static final Object PRESENT = new Object();

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

也是和 HashSet 一样,令对应的 Map 的 value 域为一个随便不要的对象就行。

其他的方法如:

public boolean remove(Object o) {
    return m.remove(o)==PRESENT;
}
public void clear() {
    m.clear();
}

等等都是类似的,这里不再累赘。

转载于:https://my.oschina.net/niclee94/blog/1536545

你可能感兴趣的:(java)