知识模块
☕ Java 知识模块
二、Java 集合框架
HashSet vs TreeSet

HashSet vs TreeSet

HashSet 和 TreeSet 是 Java 集合框架中 Set 接口的两个核心实现类。Set 的特点是不允许重复元素。理解两者的实现原理和性能差异,是正确选择使用场景的关键。


一、Set 接口概述

1.1 Set 的特点

特点说明
不重复不允许存储重复元素
无索引没有提供通过索引访问元素的方法
最多一个 null最多允许一个 null 元素(TreeSet 不允许)
public interface Set<E> extends Collection<E> {
    // 基本操作
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    boolean add(E e);
    boolean remove(Object o);
    
    // 批量操作
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
    boolean removeAll(Collection<?> c);
    boolean retainAll(Collection<?> c);
    
    // 集合运算
    // 并集:addAll
    // 交集:retainAll
    // 差集:removeAll
}

1.2 Set 实现类一览

                    ┌─────────────┐
                    │    Set<E>   │
                    └──────┬──────┘

        ┌──────────────────┼──────────────────┐
        │                  │                  │
  ┌─────┴─────┐      ┌─────┴─────┐      ┌─────┴─────┐
  │  HashSet  │      │  TreeSet  │      │LinkedHashSet│
  └───────────┘      └───────────┘      └───────────┘
  哈希表实现          红黑树实现           哈希表+链表
  无序                有序                插入顺序
  O(1)                O(log n)            O(1)

二、HashSet

2.1 底层实现

HashSet 基于 HashMap 实现,元素存储在 HashMap 的 key 中,value 是一个固定的 PRESENT 对象。

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {
    
    // 内部使用 HashMap
    private transient HashMap<E,Object> map;
    
    // 虚拟值,作为 HashMap 的 value
    private static final Object PRESENT = new Object();
    
    // 构造器
    public HashSet() {
        map = new HashMap<>();
    }
    
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }
    
    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }
}

2.2 核心方法

// 添加元素:调用 HashMap 的 put
public boolean add(E e) {
    retu