java集合详解 - TreeSet详解

TreeSet 是 Java 集合框架中的一个重要实现类,它基于 TreeMap(红黑树)实现,具有元素唯一自动排序的特性。它继承自 AbstractSet,并实现了 NavigableSet 接口,支持范围查询和导航操作。

目录

TreeSet 的特点

TreeSet 排序规则

(1) 自然排序(Comparable)

(2) 自定义排序(Comparator)

TreeSet vs HashSet

使用范围 

TreeSet 常用方法 

(1) 添加元素

(2) 删除元素

(3) 查询元素

 (4) 范围查询(NavigableSet 方法)

 (5) 遍历方式

        迭代器遍历

        降序遍历 


TreeSet 的特点

  • 元素唯一:不允许重复值(基于 equals() 和 compareTo() 判断)。

  • 自动排序:默认按元素的自然顺序Comparable)排序,或通过 Comparator 自定义排序规则。

  • 基于红黑树(Red-Black Tree):查询、插入、删除的时间复杂度为 O(log n)

  • 线程不安全:多线程环境下需要手动同步(如使用 Collections.synchronizedSortedSet)。

  • 允许 null(仅当使用自定义 Comparator 时):默认情况下,TreeSet 不允许 null,否则会抛出 NullPointerException

TreeSet 排序规则

(1) 自然排序(Comparable)

元素必须实现 Comparable 接口,否则会抛出 ClassCastException

class Person implements Comparable {
    String name;
    int age;

    @Override
    public int compareTo(Person other) {
        return this.age - other.age; // 按年龄排序
    }
}

TreeSet people = new TreeSet<>();
people.add(new Person("Alice", 25));
people.add(new Person("Bob", 20));
// 按年龄升序排列

(2) 自定义排序(Comparator)

可以在构造 TreeSet 时传入 Comparator 进行自定义排序。

// 按字符串长度排序
TreeSet words = new TreeSet<>(
    Comparator.comparingInt(String::length)
);
words.add("Apple");
words.add("Banana");
words.add("Orange");
System.out.println(words); // [Apple, Banana, Orange]

TreeSet vs HashSet

特性 TreeSet HashSet
底层结构 红黑树(TreeMap 哈希表(HashMap
排序 自动排序 无序
时间复杂度 O(log n) O(1)(平均)
允许 null 仅当自定义 Comparator 允许时 允许
线程安全 不安全 不安全
适用场景 需要排序、范围查询 只需快速查找

使用范围 

  • TreeSet 适用于需要排序和范围查询的场景

  • 默认按自然顺序排序,也可自定义 Comparator

  • 查询、插入、删除的时间复杂度为 O(log n)

  • 线程不安全,需手动同步

    使用场景举例

  • 存储有序且不重复的数据(如排行榜)。

  • 需要快速查找最小/最大值(first() / last())。

  • 需要范围查询(如 subSet() / headSet())。

TreeSet 常用方法 

(1) 添加元素

方法 说明
boolean add(E e) 添加元素,成功返回 true,重复返回 false
boolean addAll(Collection c) 添加集合中的所有元素。
TreeSet nums = new TreeSet<>();
nums.add(5);
nums.add(2);
nums.add(8);
System.out.println(nums); // [2, 5, 8]

(2) 删除元素

方法 说明
boolean remove(Object o) 删除指定元素,成功返回 true,否则 false
void clear() 清空所有元素。
TreeSet nums = new TreeSet<>(Set.of(2, 5, 8));
nums.remove(5);
System.out.println(nums); // [2, 8]
nums.clear();
System.out.println(nums); // []

(3) 查询元素

方法 说明
boolean contains(Object o) 判断是否包含指定元素。
E first() 返回第一个(最小)元素。
E last() 返回最后一个(最大)元素。
E floor(E e) 返回 ≤ 给定元素的最大元素。
E ceiling(E e) 返回 ≥ 给定元素的最小元素。
E lower(E e) 返回 < 给定元素的最大元素。
E higher(E e) 返回 > 给定元素的最小元素。
TreeSet nums = new TreeSet<>(Set.of(2, 5, 8, 10));

System.out.println(nums.first());  // 2
System.out.println(nums.last());  // 10

System.out.println(nums.floor(6));  // 5 (≤6 的最大值)
System.out.println(nums.ceiling(6));  // 8 (≥6 的最小值)

System.out.println(nums.lower(5));  // 2 (<5 的最大值)
System.out.println(nums.higher(5));  // 8 (>5 的最小值)

 (4) 范围查询(NavigableSet 方法)

方法 说明
SortedSet headSet(E toElement) 返回 < toElement 的所有元素。
SortedSet tailSet(E fromElement) 返回 ≥ fromElement 的所有元素。
SortedSet subSet(E fromElement, E toElement) 返回 [fromElement, toElement) 的元素。
NavigableSet descendingSet() 返回逆序的 TreeSet
TreeSet nums = new TreeSet<>(Set.of(2, 5, 8, 10));

System.out.println(nums.headSet(6));  // [2, 5] (<6)
System.out.println(nums.tailSet(5));  // [5, 8, 10] (≥5)
System.out.println(nums.subSet(3, 9));  // [5, 8] (≥3 且 <9)
System.out.println(nums.descendingSet());  // [10, 8, 5, 2] (逆序)

 (5) 遍历方式

        迭代器遍历
TreeSet fruits = new TreeSet<>(Set.of("Apple", "Banana", "Orange"));
for (String fruit : fruits) {
    System.out.println(fruit);
}
        降序遍历 
Iterator it = fruits.descendingIterator();
while (it.hasNext()) {
    System.out.println(it.next());
}

HashMap详解 HashLink详解 ArrayList详解 CopyOnWriteArrayList详解 HashSet详解 LinkedHashMap详解 LinkedHashSet详解

你可能感兴趣的:(java,开发语言)