227. Java 集合 - 排序Set中的元素 —— SortedSet 与 NavigableSet

227. Java 集合 - 排序Set中的元素 —— SortedSet 与 NavigableSet


1. 🔹 Set还能排序?是的!SortedSet了解一下!

除了普通的Set接口,Java还提供了两个强大的扩展接口:

  • SortedSet
  • NavigableSet

这两个接口都是为了让集合中的元素保持排序状态而设计的!


2. 🚀 什么是SortedSet?

SortedSet接口的特点是:
集合中的元素始终按照升序排列(从小到大)。

📢 重要提醒:具体如何实现排序,是由具体的集合实现类(比如TreeSet)来决定的。


2.1 📌 排序需要比较,那元素怎么比较?

为了让元素可以排序,Java提供了两种标准的比较方式:

方式 描述
1. 实现Comparable接口 元素自己知道怎么比较自己,定义compareTo()方法
2. 提供一个Comparator 在创建集合时指定外部比较器

🔹 即使元素本身已经实现了Comparable,你仍然可以通过Comparator来指定不同的排序规则,灵活切换排序方式!


2.2 🛠️ 示例:使用TreeSet(实现了SortedSet)

import java.util.*;

public class SortedSetExample {
    public static void main(String[] args) {
        // 使用元素自带的自然排序(字母顺序)
        SortedSet<String> names = new TreeSet<>();
        names.add("Charlie");
        names.add("Alice");
        names.add("Bob");

        System.out.println("Sorted names: " + names);

        // 使用Comparator自定义逆序排序
        SortedSet<String> reversedNames = new TreeSet<>(Comparator.reverseOrder());
        reversedNames.addAll(names);

        System.out.println("Reversed sorted names: " + reversedNames);
    }
}

运行输出

Sorted names: [Alice, Bob, Charlie]
Reversed sorted names: [Charlie, Bob, Alice]

3. 🎯 排序(Sorting) vs 顺序(Ordering)

这两个概念非常重要,经常会被混淆:

排序(Sorting) 顺序(Ordering)
定义 根据比较逻辑,将元素从小到大(或自定义规则)排列 保持元素添加进集合的顺序
例子 SortedSet List
特点 第一个元素总是最小的 第一个元素总是最先添加的
实现 TreeSet ArrayList / LinkedList

4. 📚 SortedSet支持的新操作

在普通Set基础上,SortedSet增加了以下操作:

✅ 获取最小元素(first())和最大元素(last()
✅ 截取某一范围内的元素:

  • headSet(E toElement):取出比指定元素小的所有元素
  • tailSet(E fromElement):取出比指定元素大的所有元素 ✅ 迭代时总是从最小元素开始,到最大元素结束

5. 🔥 再升级:NavigableSet!

NavigableSetSortedSet的子接口,它增加了更多灵活操作,比如:

✅ 可以反向遍历元素(从大到小)
✅ 更方便地获取:

  • 刚好小于某元素的元素(lower()
  • 刚好大于某元素的元素(higher()
  • 小于等于floor()
  • 大于等于ceiling()

🛠️ 示例:NavigableSet操作

import java.util.*;

public class NavigableSetExample {
    public static void main(String[] args) {
        NavigableSet<Integer> numbers = new TreeSet<>(Arrays.asList(10, 20, 30, 40, 50));

        System.out.println("Numbers: " + numbers);

        System.out.println("Lower than 30: " + numbers.lower(30)); // 20
        System.out.println("Higher than 30: " + numbers.higher(30)); // 40
        System.out.println("Floor of 30: " + numbers.floor(30)); // 30
        System.out.println("Ceiling of 25: " + numbers.ceiling(25)); // 30

        // 反向遍历
        System.out.println("Descending order: " + numbers.descendingSet());
    }
}

运行输出

Numbers: [10, 20, 30, 40, 50]
Lower than 30: 20
Higher than 30: 40
Floor of 30: 30
Ceiling of 25: 30
Descending order: [50, 40, 30, 20, 10]

📌 小总结

特性 SortedSet NavigableSet
是否升序排列?
是否支持范围查询?
是否支持反向遍历? ✅ 是
是否能方便地取floor/ceiling等? ✅ 是

🎤 小建议

  • 举例互动

    “如果我想要一个集合,不但去重,还要求元素自动按大小排列,我该选哪个?(答案:TreeSet)”

  • 小结过渡

    “我们了解了Set还能排序,那么下一步,咱们来看看Map接口,它也可以排序!而且,Map中是存储‘键值对’哦!”

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容