Java8 Comparator接口 和 List Steam 排序使用案例

在Java中,Comparator接口主要用于实现自定义排序逻辑,适用于未实现Comparable接口或需要覆盖默认比较规则的场景。以下是核心使用方法和注意事项:

一、基础用法

  1. 匿名内部类实现
    传统方式通过匿名内部类重写compare()方法,例如对整数降序排序:

    List<Integer> list = Arrays.asList(3, 1, 2); 
    list.sort(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) {// 降序 return o2 - o1; } } );

    此方式在Java 8之前常见。

  2. Lambda表达式简化
    Java 8后可用Lambda替代匿名类,代码更简洁:

    list.sort((o1, o2) -> o2 - o1);

    或使用方法引用:

    list.sort(Comparator.reverseOrder());

    适用于简单排序场景。

二、高级特性

  1. 多条件排序
    使用thenComparing()实现多级排序,例如先按年龄升序,再按姓名降序:

    List<Person> people = ...; 
    people.sort( Comparator.comparing(Person::getAge) .thenComparing(Comparator.comparing(Person::getName).reversed() ) );

    支持链式调用,灵活组合排序规则。

  2. 处理null值
    需显式处理null避免NullPointerException,例如将null排在末尾:

    list.sort((a, b) -> {if (a == null) return 1;if (b == null) return -1; return a.compareTo(b);});

    注意违反自反性会导致Comparison method violates its general contract错误。

三、Comparator与Comparable对比

维度ComparatorComparable
实现位置独立类或匿名类目标类内部实现
排序规则支持多种自定义规则仅提供单一自然排序
侵入性无侵入,不影响原有类需修改类结构
典型应用场景第三方类排序、多规则排序类自身有明确排序逻辑(如String)

优先使用Comparator实现灵活排序,尤其是需要动态调整规则时。

四、常见问题

  1. 整数溢出风险
    避免直接返回o1 - o2,应使用
    Integer.compare(o1, o2)。
  2. JDK8增强方法
    • Comparator.naturalOrder():自然排序
    • Comparator.nullsFirst():将null置于开头
    • Comparator.comparingInt():避免装箱开销68。

通过合理应用Comparator,可高效实现复杂排序需求,同时保持代码可维护性。

Java 8的 Stream API 提供了强大的List排序功能,主要通过sorted()方法实现,支持自然排序、自定义排序以及多条件组合排序。以下是核心用法总结:

1. 基础排序

  • 自然排序(升序)‌:直接调用sorted()方法,元素需实现Comparable接口
    list.stream().sorted().collect(Collectors.toList()); 
  • 降序排序‌:通过Comparator.reverseOrder()reversed()方法
    list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());// 或 
    list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList());

2. 自定义排序

  • 单字段排序‌:使用Comparator.comparing()指定字段
    list.stream().sorted(Comparator.comparing(Student::getScore)).collect(Collectors.toList());
  • 多字段排序‌:通过thenComparing()链式调用
    list.stream() .sorted(Comparator.comparing(Student::getAge)   .thenComparing(Student::getName)) .collect(Collectors.toList());

3. 空值处理

  • 空值优先/后置‌:使用Comparator.nullsFirst()Comparator.nullsLast()
    list.stream() .sorted(Comparator.comparing(Student::getAge,           Comparator.nullsFirst(Integer::compareTo))) .collect(Collectors.toList());

4. 性能提示

  • sorted()操作对大型流可能较昂贵,若数据已排序可跳过此操作2
  • 复杂排序建议预编译Comparator以减少重复计算9

完整示例:

List<Student> students = Arrays.asList( new Student("Alice", 25), new Student("Bob", 20) );List<Student> sorted = students.stream() .sorted(Comparator.comparing(Student::getAge).reversed()) .collect(Collectors.toList());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/96083.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/96083.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

word2vec模型案例

代码实现&#xff1a;import torch.optim as optim from tqdm import tqdm, trange import numpy as np import torch from torch import nn import torch.nn.functional as FCONTEXT_SIZE 2raw_text """We are about to study the idea of a computational p…

< 自用文 OS 有关 > (续)发现正在被攻击 后的自救 Fail2ban + IPset + UFW 工作流程详解

继上编&#xff1a;&#xff1c; 自用文 主机 USC 记录&#xff1a;&#xff1e; 发现正在被攻击 后的自救-CSDN博客 环境&#xff1a; 改进&#xff1a; 以下是把代码&#xff0c;懒得写&#xff0c;扔给了 AI &#xff0c;让它出的&#xff1a; Fail2ban IPset UFW 工作…

Linux —— 虚拟进程地址空间

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录虚…

简单聊一聊js

JavaScript 是一种高级的、解释型的编程语言。它是现代 Web 开发的三大核心基石之一&#xff0c;与 HTML 和 CSS 并列。​HTML​&#xff1a;负责网页的结构和内容​&#xff08;如标题、段落、图片&#xff09;。​CSS​&#xff1a;负责网页的样式和布局​&#xff08;如颜色…

造粒机cad+设计说明书

摘要 随着现代化工业的快速发展&#xff0c;生产出大量的固体废弃物。这些废弃物对环境造成了很大的污染&#xff0c;因此需要采取有效的措施进行处理。机械强压式造粒机就是一种非常有效的处理工具&#xff0c;它可以将废渣、废料、饲料和化肥等材料通过机械强力挤压&#xff…

第五课 C#语言基本元素概览,初始类型,变量与方法,算法简介

熟悉C#语言要求&#xff1a;对构成C#语言的基本元素&#xff0c;随便拿出一个你都认识&#xff0c;对于常见基本元素&#xff0c;都能正确使用它 精通C#语言要求&#xff1a;对于构成C#语言的基本元素&#xff0c;随便拿出一个都会使用&#xff0c;对于常用基本元素&#xff0…

LLM学习:大模型基础——视觉大模型以及autodl使用

1、常见的VLM 在大模型中,VLM 是视觉语言模型(Vision-Language Model)的缩写,是一种多模态、生成式 AI 模型,能够理解和处理视频、图像和文本。 VLM 通过将大语言模型(LLM)与视觉编码器相结合构建而成,使 LLM 具有 “看” 的能力,从而可以处理并提供对提示中的…

Vue—路由配置中设置了meta.title,但页面标题仍然显示为“Vite App“?【让我来看看~】

路由配置中明明设置了meta.title&#xff0c;但是页面标题仍然显示为"Vite App"&#xff1f;这是因为仅仅在路由配置中设置meta.title是不够的&#xff0c;还需要在路由守卫中动态设置页面标题。需要做以下几件事来正确设置页面标题&#xff1a;1.首先更新HTML文件的…

【机器学习】综合实训(二)

项目五 电影评分预测【教学内容】使用 MovieLens 数据集&#xff0c;训练一个模型预测用户对电影的评分。主要有以下几个知识点&#xff1a;&#xff08;1&#xff09;数据加载与探索性分析&#xff08;EDA&#xff09;。&#xff08;2&#xff09;处理稀疏数据&#xff08;如用…

STM32 UART + DMA + 空闲中断使用中的帧错误(FE)问题及解决方案

STM32 UART + DMA + IDLE中断使用中的帧错误(FE)问题及解决方案 在我调试STM32H7串口空闲中断DMA接受时遇到了一个bug,这个现象发生在系统刚上电时,有个串口由于帧错误FE挂起了中断,之后在HAL_UART_IRQHandler这个全局中断处理函数结束后,所有的中断使能标志位都被清除了,经过…

TDengine 选择函数 BOTTOM() 用户手册

BOTTOM() 函数用户手册 函数定义 BOTTOM(expr, k)功能说明 BOTTOM() 函数统计表/超级表中某列的值最小 k 个非 NULL 值。如果多条数据取值一样&#xff0c;全部取用又会超出 k 条限制时&#xff0c;系统会从相同值中随机选取符合要求的数量返回。 返回值 数据类型: 同应用…

西门子 S7-200 SMART PLC 实现星三角降压启动控制:原理、案例与完整程序

在工业控制场景中&#xff0c;中型异步电机直接启动时会产生远超额定电流的冲击电流&#xff08;通常为额定电流的 5-7 倍&#xff09;&#xff0c;不仅会影响电网稳定性&#xff0c;还可能对机械设备造成损伤。星三角&#xff08;Y-Δ&#xff09;降压启动是解决这一问题的经典…

【Android】View 的基础知识

【Android】View 的基础知识 1. 什么是 View&#xff1f; View 是 Android 中所有UI组件的基础类。它表示屏幕上的一个矩形区域&#xff0c;负责绘制内容和处理用户交互事件。所有的 UI 组件&#xff08;如按钮、文本框等&#xff09;都是 View 的子类&#xff0c;而 ViewGroup…

西门子 S7-200 SMART PLC 实现电机点动与连续运行综合控制

在工业生产中&#xff0c;电机控制并非单一模式&#xff1a;调试设备时需要 “按动即转、松开即停” 的点动功能&#xff0c;正常生产时则需要 “一键启动、持续运行” 的连续控制。本文以西门子 S7-200 SMART PLC 为载体&#xff0c;详细讲解电机点动控制原理&#xff0c;并设…

如何解决pip安装报错ModuleNotFoundError: No module named ‘sphinx-rtd-theme’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘sphinx-rtd-theme’问题 摘要 在使用 PyCharm 开发 Python 项目时&#xff0c;pip install 报错是常见痛点。特别是在构建文档或引入第三方库时&#xff0c;开…

HakcMyVM-Literal

目录信息搜集漏洞利用权限提升信息搜集 主机发现 ┌──(kali㉿kali)-[~] └─$ nmap -sn 192.168.21.0/24 Nmap scan report for 192.168.21.5端口扫描 ┌──(kali㉿kali)-[~] └─$ nmap -sS -sV -O -p- 192.168.21.5 Starting Nmap 7.95 ( https://nmap.org ) a…

0904 类的继承

Part 1.梳理思维导图一.继承中的特殊成员函数1.构造函数父类的构造函数会被继承到子类中&#xff0c;在构造的顺序中&#xff0c;是先构造父类&#xff0c;再构造子类#include <iostream>using namespace std;class Father { public:string name; protected:int *age; pr…

PDF教程|如何把想要的网页保存下来?

前段时间有个小伙伴咨询了小白&#xff1a;领导想要某个网页的整个页面&#xff0c;有没有比较好的方法把它保存下来&#xff1f; 在他找到小白之前&#xff0c;这种事情他已经接到好几次了&#xff0c;每次都是怎么解决的呢&#xff1f;其实很简单&#xff0c;就是打开Word&a…

【bash】命令查看当前目录下文件个数

要用 ls 查看当前目录下的文件个数&#xff0c;可以结合 wc -l 来统计行数&#xff1a; ls -1 | wc -l说明&#xff1a; ls -1&#xff1a;以一行一个文件的方式列出。wc -l&#xff1a;统计行数&#xff0c;也就是文件/目录的数量。 ⚠️ 需要注意&#xff1a; 这个方法会把文…

「日拱一码」081 机器学习——梯度增强特征选择GBFS

目录 什么是梯度增强特征选择&#xff08;GBFS&#xff09; 为什么 GBM 适合做特征选择 GBFS 的一般步骤 代码示例 什么是梯度增强特征选择&#xff08;GBFS&#xff09; GBFS 并非一个像 Lasso 或随机森林那样有严格标准定义的独立算法&#xff0c;而是一种基于梯度提升机…