0Pricing
Java Academy · 课时

TreeSet 与 NavigableSet

存储有序且不重复的元素,并使用 floor、ceiling、higher 和 lower 查询最近邻元素

TreeSet 与 NavigableSet 是 CoddyKit 上的免费 Java Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。

什么是 TreeSet?

TreeSet 是一种由红黑树支持的有序集合。它按升序自然顺序(或指定的 Comparator)存储不重复的元素。所有操作的复杂度均为 O(log n)。

import java.util.TreeSet;

TreeSet<String> names = new TreeSet<>();
names.add("Charlie");
names.add("Alice");
names.add("Bob");
names.add("Alice"); // duplicate ignored

for (String s : names) System.out.print(s + " ");
// Alice Bob Charlie

NavigableSet 方法:floor、ceiling、lower、higher

TreeSet 实现了 NavigableSet,提供用于查找最接近元素的导航方法:

TreeSet<Integer> set = new TreeSet<>();
for (int i = 10; i <= 50; i += 10) set.add(i);
// {10, 20, 30, 40, 50}

System.out.println(set.floor(25));   // 20 (greatest ≤ 25)
System.out.println(set.ceiling(25)); // 30 (smallest ≥ 25)
System.out.println(set.lower(30));   // 20 (strictly less)
System.out.println(set.higher(30));  // 40 (strictly greater)

first、last、pollFirst、pollLast

访问或移除边界元素:

TreeSet<String> ts = new TreeSet<>(Set.of("cherry","apple","banana","date"));

System.out.println(ts.first());       // apple
System.out.println(ts.last());        // date
System.out.println(ts.pollFirst());   // apple (removed)
System.out.println(ts.pollLast());    // date (removed)
System.out.println(ts);              // [banana, cherry]

headSet、tailSet、subSet

提取有序的子集视图:

TreeSet<Integer> set = new TreeSet<>(Set.of(1,2,3,4,5,6,7,8,9,10));

System.out.println(set.headSet(5));      // [1, 2, 3, 4]
System.out.println(set.tailSet(7));      // [7, 8, 9, 10]
System.out.println(set.subSet(3, 7));    // [3, 4, 5, 6]

// Inclusive upper bound:
System.out.println(set.subSet(3, true, 7, true)); // [3,4,5,6,7]

降序遍历

使用 descendingIterator() 或 descendingSet() 实现逆序:

TreeSet<Integer> ts = new TreeSet<>(Set.of(1,3,5,7,9));

// Descending iterator
var it = ts.descendingIterator();
while (it.hasNext()) System.out.print(it.next() + " ");
// 9 7 5 3 1

通过 Comparator 自定义顺序

传入 Comparator,按非自然顺序排序——例如让最长字符串排在最前面:

TreeSet<String> byLength = new TreeSet<>(
    Comparator.comparingInt(String::length)
              .thenComparing(Comparator.naturalOrder())
);
byLength.add("Hi");
byLength.add("Hello");
byLength.add("Hey");
byLength.add("Java");

for (String s : byLength) System.out.print(s + " ");
// Hi Hey Java Hello

使用场景:有序的不重复用户名

将用户名存储在 TreeSet 中,即可自动去重并保持字母顺序:

TreeSet<String> users = new TreeSet<>();
users.add("alice");
users.add("bob");
users.add("alice"); // ignored
users.add("carol");

System.out.println(users.first()); // alice
System.out.println(users);         // [alice, bob, carol]

使用场景:范围计数

使用 subSet 统计范围内的元素数量:

TreeSet<Integer> scores = new TreeSet<>();
for (int s : new int[]{45,62,78,55,90,88,34,71}) scores.add(s);

// Scores between 60 and 89 (inclusive)
int count = scores.subSet(60, true, 89, true).size();
System.out.println("Students in B range: " + count); // 3 (62, 78, 88... wait: 62,78,71,88=4)
// Actually: 62,71,78,88 = 4

TreeSet 与 HashSet、LinkedHashSet

请根据需求选择:

  • HashSet:操作复杂度为 O(1),无序
  • LinkedHashSet:操作复杂度为 O(1),按插入顺序排列
  • TreeSet:操作复杂度为 O(log n),有序,并提供导航方法

TreeSet 要求元素实现 Comparable 或提供 Comparator。

空值元素

TreeSet 在使用自然顺序时不允许(NOT)空值元素——因为空值无法比较,所以会抛出 NullPointerException。显式处理空值的自定义 Comparator 可以正常工作。

TreeSet<String> ts = new TreeSet<>();
try {
    ts.add(null); // throws NullPointerException
} catch (NullPointerException e) {
    System.out.println("Cannot add null: " + e);
}

线程安全

TreeSet 不是线程安全的。请使用 Collections.synchronizedSortedSet() 在外部进行同步,或者使用同时有序且线程安全的 ConcurrentSkipListSet。

快速检查

一个 TreeSet<Integer> 包含 {10, 20, 30, 40, 50}。set.ceiling(35) 会返回什么?

回顾:TreeSet 与 NavigableSet

要点:

  • TreeSet 存储不重复的有序元素(O(log n))
  • 实现 NavigableSet:floor、ceiling、lower、higher、first、last
  • headSet、tailSet、subSet 返回由原映射支持的范围视图
  • 使用 descendingSet()/descendingIterator() 实现逆序
  • 不是线程安全的——并发使用请改用 ConcurrentSkipListSet

常见问题解答

「TreeSet 与 NavigableSet」课时是免费的吗?

是的 — 「TreeSet 与 NavigableSet」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。

「TreeSet 与 NavigableSet」这节课中我会学到什么?

存储有序且不重复的元素,并使用 floor、ceiling、higher 和 lower 查询最近邻元素 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Java Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「TreeSet 与 NavigableSet」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Java Academy 课中编写并运行代码吗?

能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. TreeMap:有序键值对
  2. 子映射与范围视图
  3. TreeSet 与 NavigableSet
  4. Tree 集合中的自定义排序
← 返回 Java Academy