详细解释一下Stream API中的sorted操作

简介: 详细解释一下Stream API中的sorted操作

在 Java Stream API 中,sorted 是用于对数据流进行排序的中间操作,它会返回一个新的有序流(元素按指定规则排序),且不会修改原始集合。sorted 操作有两种重载形式,分别支持自然排序自定义排序,适用于需要对元素顺序进行调整的场景(如按数值大小、字符串长度、对象属性等排序)。

一、sorted 操作的两种形式

1. 自然排序:sorted()

  • 适用场景:流中的元素类型实现了 java.lang.Comparable 接口(如 IntegerStringLocalDate 等),可直接按其默认规则排序。
  • 原理:调用元素自身的 compareTo 方法进行比较(例如 Integer 按数值大小,String 按字典序)。

示例:对整数流进行自然排序(升序)

List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5);
numbers.stream()
       .sorted() // 自然排序(Integer实现了Comparable)
       .forEach(System.out::print); // 输出:1 1 3 4 5

示例:对字符串流进行自然排序(字典序)

List<String> words = Arrays.asList("banana", "apple", "cherry");
words.stream()
     .sorted() // 按字符串字典序(A-Z)
     .forEach(System.out::println); 
// 输出:
// apple
// banana
// cherry

2. 自定义排序:sorted(Comparator<T> comparator)

  • 适用场景:元素未实现 Comparable,或需要按自定义规则排序(如降序、按对象属性排序等)。
  • 原理:通过传入 java.util.Comparator 接口的实现类(通常用 Lambda 表达式或方法引用简化),定义元素的比较规则。

示例 1:按整数降序排序

List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5);
numbers.stream()
       .sorted((a, b) -> b.compareTo(a)) // 自定义比较器(降序)
       .forEach(System.out::print); // 输出:5 4 3 1 1

也可使用 Comparator 工具类简化:

import static java.util.Comparator.reverseOrder;

numbers.stream()
       .sorted(reverseOrder()) // 等价于上述降序逻辑
       .forEach(System.out::print);

示例 2:按字符串长度排序(短→长)

List<String> words = Arrays.asList("banana", "apple", "cherry", "a");
words.stream()
     .sorted((s1, s2) -> Integer.compare(s1.length(), s2.length())) // 按长度比较
     .forEach(System.out::println); 
// 输出:
// a
// apple(5)
// banana(6)
// cherry(6)

使用方法引用进一步简化:

import static java.util.Comparator.comparingInt;

words.stream()
     .sorted(comparingInt(String::length)) // 按长度排序(Comparator工具类)
     .forEach(System.out::println);

示例 3:按对象属性排序
假设有 User 类(含 age 属性),需按年龄升序排序:

class User {
   
    private String name;
    private int age;
    // 构造器、getter省略
    public User(String name, int age) {
    this.name = name; this.age = age; }
    public int getAge() {
    return age; }
    public String getName() {
    return name; }
}

List<User> users = Arrays.asList(
    new User("Bob", 20),
    new User("Alice", 18),
    new User("Charlie", 25)
);

// 按年龄升序排序
users.stream()
     .sorted(comparingInt(User::getAge)) // 引用User的age属性
     .forEach(user -> System.out.println(user.getName() + "(" + user.getAge() + ")"));
// 输出:
// Alice(18)
// Bob(20)
// Charlie(25)

二、sorted 操作的关键特性

  1. 中间操作,惰性求值
    sorted 本身不会执行排序,仅在终端操作(如 forEachcollect)触发时才会执行排序逻辑。

  2. 稳定性
    对于并行流,sorted 保证排序结果与串行流一致(即稳定排序),但排序过程可能利用多线程加速。

  3. 有序性(Ordering)

    • 若原始流是有序的(如 List 的流),sorted 会返回一个新的有序流(排序后的顺序)。
    • 若原始流是无序的(如 HashSet 的流),sorted 会强制返回有序流(排序后的顺序)。
    • 注意:并行流的 sorted 操作可能比串行流更耗时(因排序本身是CPU密集型,且并行需额外的线程协调)。
  4. 不修改原始集合
    sorted 仅对“流中的元素”进行排序,原始集合的元素顺序不会改变。

三、使用注意事项

  1. 避免对大集合频繁排序
    排序的时间复杂度通常为 O(n log n),对超大集合(如百万级元素)使用 sorted 可能影响性能,需评估是否必要。

  2. Comparator 的实现需满足规范
    自定义比较器时,需保证 compare(a, b) 满足:

    • 自反性:compare(a, a) = 0
    • 对称性:compare(a, b) = -compare(b, a)
    • 传递性:若 compare(a, b) > 0compare(b, c) > 0,则 compare(a, c) > 0
      否则可能导致排序结果异常(如 NullPointerException 或不稳定排序)。
  3. 处理 null 元素
    若流中包含 null 元素,自然排序(Comparable)会抛出 NullPointerException,需在自定义比较器中显式处理 null(例如将 null 排在最前或最后):

    List<String> words = Arrays.asList("banana", null, "apple");
    words.stream()
         .sorted((s1, s2) -> {
         
             if (s1 == s2) return 0;
             if (s1 == null) return -1; // null排在前面
             if (s2 == null) return 1;
             return s1.compareTo(s2);
         })
         .forEach(System.out::println);
    // 输出:
    // null
    // apple
    // banana
    

四、总结

sorted 操作是 Stream API 中用于排序的核心工具,通过两种形式支持灵活的排序需求:

  • sorted():依赖元素的 Comparable 接口,实现自然排序;
  • sorted(Comparator):通过自定义比较器,实现按任意规则排序(如降序、属性排序等)。

使用时需注意其惰性求值特性、有序性影响及性能开销,合理结合其他流操作(如 filterlimit)可高效处理排序后的数据流。

目录
相关文章
|
3天前
|
弹性计算 人工智能 安全
云上十五年——「弹性计算十五周年」系列客户故事(第二期)
阿里云弹性计算十五年深耕,以第九代ECS g9i实例引领算力革新。携手海尔三翼鸟、小鹏汽车、微帧科技等企业,实现性能跃升与成本优化,赋能AI、物联网、智能驾驶等前沿场景,共绘云端增长新图景。
|
9天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
8天前
|
人工智能 自然语言处理 自动驾驶
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
|
8天前
|
云安全 人工智能 自然语言处理
阿里云x硅基流动:AI安全护栏助力构建可信模型生态
阿里云AI安全护栏:大模型的“智能过滤系统”。
|
9天前
|
编解码 自然语言处理 文字识别
Qwen3-VL再添丁!4B/8B Dense模型开源,更轻量,仍强大
凌晨,Qwen3-VL系列再添新成员——Dense架构的Qwen3-VL-8B、Qwen3-VL-4B 模型,本地部署友好,并完整保留了Qwen3-VL的全部表现,评测指标表现优秀。
661 7
Qwen3-VL再添丁!4B/8B Dense模型开源,更轻量,仍强大
|
4天前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
|
11天前
|
存储 机器学习/深度学习 人工智能
大模型微调技术:LoRA原理与实践
本文深入解析大语言模型微调中的关键技术——低秩自适应(LoRA)。通过分析全参数微调的计算瓶颈,详细阐述LoRA的数学原理、实现机制和优势特点。文章包含完整的PyTorch实现代码、性能对比实验以及实际应用场景,为开发者提供高效微调大模型的实践指南。
787 2
|
2天前
|
编解码 文字识别 算法
一张图能装下“千言万语”?DeepSeek-OCR 用视觉压缩长文本,效率提升10倍!
一张图能装下“千言万语”?DeepSeek-OCR 用视觉压缩长文本,效率提升10倍!
344 10