使用Stream流对集合排序

2023-10-27

0 写在前面

有一些业务需要对集合按照一些规则进行排序,本篇介绍如何用Stream()对集合进行升序或者降序操作。

之前只有接触过使用数据库进行排序,有一些情况需要不同的排序结果,如果进行多次查询会多次操作数据库,所以有些地方使用流对集合操作是更好的选择。

1 格式

1.1 介绍:

Stream 流 -> 调用 sorted 方法 -> 方法内传入对比规则,用容器对象的属性作为入参作为排序依据,默认升序,需要倒叙的话后面调用.reversed() 方法

1.2 单个属性排序格式:

升序:list.stream().sorted(Comparator.comparing(实体::get属性)).collect(Collectors.toList());

例如:

	personnelList.stream().sorted(Comparator.comparing(Personnel::getId)).collect(Collectors.toList());

降序:list.stream().sorted(Comparator.comparing(实体::get属性).reversed()).collect(Collectors.toList());

	personnelList.stream().sorted(Comparator.comparing(Personnel::getId).reversed()).collect(Collectors.toList());

1.3 多个属性排序格式:

只需在比较后面加上 thenComparing 方法

集合.stream().sorted(Comparator.comparing(实体::get属性).thenComparing(实体::get属性)).collect(Collectors.toList());,

例如:

personnels.stream().sorted(Comparator.comparing(Personnel::getName, Comparator.nullsLast(String::compareTo))
                        .thenComparing(Personnel::getEmail))
                .collect(Collectors.toList());

1.4 注意事项

只对属性进行排序(此属性是封装类)该属性有为 null 的情况会报错

此时需要 在Comparator.comparing()入参多加一个nullsLast()的方法

例如对单个排序:

personnelList.stream()
                .sorted(Comparator.comparing(Personnel::getId, Comparator.nullsLast(Integer::compareTo)))
                .collect(Collectors.toList());

例如对多个排序:

personnels.stream().sorted(Comparator.comparing(Personnel::getName, Comparator.nullsLast(String::compareTo))
    .thenComparing(Personnel::getEmail,Comparator.nullsLast(String::compareTo)))
    .collect(Collectors.toList());

2 代码举例

实体类:

import lombok.Data;

@Data
public class Personnel {

    private Integer id;

    private String name;

    private String email;

    public Personnel() {
    }

    public Personnel(int id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
}

测试类:

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class StreamSortDemo {
    @Test
    public void testDemo() {
        //模拟数据
        Personnel personnel1 = new Personnel(1, "张三", "zhangsan@zhangsan");
        Personnel personnel2 = new Personnel(3, "李四", "lisi@lisi");
        Personnel personnel3 = new Personnel(2, "王五", "wangwu@wangwu");
        //构造集合
        ArrayList<Personnel> personnelList = new ArrayList<>();
        personnelList.add(personnel1);
        personnelList.add(personnel2);
        personnelList.add(personnel3);

        //看一下原始集合--id分别为 1  3   2
        System.out.println("排序前:");
        personnelList.forEach(System.out::println);

        //1.正序输出, id 分别为 1  2   3
        List<Personnel> positiveList = personnelList.stream()
        .sorted(Comparator.comparing(Personnel::getId)).collect(Collectors.toList());
        System.out.println("升序排序后:");
        positiveList.forEach(System.out::println);

        //2. 倒序输出, id分别为 3  2   1
        List<Personnel> reversedList = personnelList.stream().sorted(Comparator.comparing(Personnel::getId).reversed())
        .collect(Collectors.toList());
        System.out.println("倒序排序后:");
        reversedList.forEach(System.out::println);


        //有null的情况
        // 只对一个属性进行排序(数字)该属性有为 null 的情况会报错  java.lang.UnsupportedOperationException
        // --对封装类Integer报错      对如果是基本数据类型int则不报错
        Personnel personnel4 = new Personnel();
        personnel4.setName("岳腾");
        personnelList.add(personnel4);
        //报错代码:
        //personnelList.stream()
        .sorted(Comparator.comparing(Personnel::getId))
        .collect(Collectors.toList());
        //解决:
        List<Personnel> aboutNullList = personnelList.stream()
                .sorted(Comparator.comparing(Personnel::getId, Comparator.nullsLast(Integer::compareTo)))
                .collect(Collectors.toList());
        System.out.println("有空值时,进行升序排序");
        aboutNullList.forEach(System.out::println);


        //利用多个属性进行排序,在比较后面加上thenComparing-
        List<Personnel> multiplePropertiesList = personnelList.stream()
                .sorted(Comparator.comparing(Personnel::getName).thenComparing(Personnel::getEmail))
                .collect(Collectors.toList());
        System.out.println("多个值进行排序进行排序:");
        multiplePropertiesList.forEach(System.out::println);

        Personnel personnel5 = new Personnel();
        personnel4.setId(5);
        personnelList.add(personnel5);


        //此时再去使用多个值,这多个值都为null的话,则会报错---->
        /*
        personnelList.stream()
                        .sorted(Comparator.comparing(Personnel::getName).thenComparing(Personnel::getEmail))
                        .collect(Collectors.toList());
         */

        // 解决方案:
        //对多个属性进行排序,在比较后面加上thenComparing,并忽略null值得属性。
        List<Personnel> multiplePropertiesAboutNullList = personnelList.stream()
                .sorted(Comparator.comparing(Personnel::getName, Comparator.nullsLast(String::compareTo)).thenComparing(Personnel::getEmail, Comparator.nullsLast(String::compareTo)))
                .collect(Collectors.toList());
        System.out.println("有空值时,多个值进行排序进行排序:");
        multiplePropertiesAboutNullList.forEach(System.out::println);
    }
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Stream流对集合排序 的相关文章

  • 如何让 BlazeDS 忽略属性?

    我有一个 java 类 它有一个带有 getter 和 setter 的字段 以及第二对 getter 和 setter 它们以另一种方式访问 该字段 public class NullAbleId private static final
  • 在 Java 中克隆对象 [3 个问题]

    这样做会调用Asub的clone方法吗 或者Asub深度克隆是否正确 如果没有的话 有没有办法通过这种方法对Asub进行深度克隆呢 abstract class Top extends TopMost protected Object cl
  • 序列的排列?

    我有具体数量的数字 现在我想以某种方式显示这个序列的所有可能的排列 例如 如果数字数量为3 我想显示 0 0 0 0 0 1 0 0 2 0 1 0 0 1 1 0 1 2 0 2 0 0 2 1 0 2 2 1 0 0 1 0 1 1 0
  • 如何在java中将一个数组列表替换为另一个不同大小的数组列表

    我有两个大小不同的数组列表 如何从此替换 ArrayList
  • 如何更改javaFX中按钮的图像?

    我正在使用javaFX 我制作了一个按钮并为此设置了图像 代码是 Image playI new Image file c Users Farhad Desktop icons play2 jpg ImageView iv1 new Ima
  • 谷歌应用程序引擎会话

    什么是java应用程序引擎 默认会话超时 如果我们将会话超时设置为非常非常长的时间 会不会产生不良影响 因为谷歌应用程序引擎会话默认情况下仅存储在数据存储中 就像facebook一样 每次访问该页面时 会话仍然永远存在 默认会话超时设置为
  • Java 集合的并集或交集

    建立并集或交集的最简单方法是什么Set在 Java 中 我见过这个简单问题的一些奇怪的解决方案 例如手动迭代这两个集合 最简单的单行解决方案是这样的 set1 addAll set2 Union set1 retainAll set2 In
  • 没有 Spring 的自定义 Prometheus 指标

    我需要为 Web 应用程序提供自定义指标 问题是我不能使用 Spring 但我必须使用 jax rs 端点 要求非常简单 想象一下 您有一个包含键值对的映射 其中键是指标名称 值是一个简单的整数 它是一个计数器 代码会是这样的 public
  • 在 junit 测试中获取 javax.lang.model.element.Element 类

    我想测试我的实用程序类 ElementUtils 但我不知道如何将类作为元素获取 在 AnnotationProcessors 中 我使用以下代码获取元素 Set
  • 如何在用户输入数据后重新运行java代码

    嘿 我有一个基本的java 应用程序 显示人们是成年人还是青少年等 我从java开始 在用户输入年龄和字符串后我找不到如何制作它它们被归类为 我希望它重新运行整个过程 以便其他人可以尝试 的节目 我一直在考虑做一个循环 但这对我来说没有用
  • Spring Boot Data JPA 从存储过程接收多个输出参数

    我尝试通过 Spring Boot Data JPA v2 2 6 调用具有多个输出参数的存储过程 但收到错误 DEBUG http nio 8080 exec 1 org hibernate engine jdbc spi SqlStat
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • 关键字“table”附近的语法不正确,无法提取结果集

    我使用 SQL Server 创建了一个项目 其中包含以下文件 UserDAO java public class UserDAO private static SessionFactory sessionFactory static se
  • 最新的 Hibernate 和 Derby:无法建立 JDBC 连接

    我正在尝试创建一个使用 Hibernate 连接到 Derby 数据库的准系统项目 我正在使用 Hibernate 和 Derby 的最新版本 但我得到的是通用的Unable to make JDBC Connection error 这是
  • Eclipse 启动时崩溃;退出代码=13

    I am trying to work with Eclipse Helios on my x64 machine Im pretty sure now that this problem could occur with any ecli
  • 找不到符号 NOTIFICATION_SERVICE?

    package com test app import android app Notification import android app NotificationManager import android app PendingIn
  • 如何将双精度/浮点四舍五入为二进制精度?

    我正在编写对浮点数执行计算的代码的测试 不出所料 结果很少是准确的 我想在计算结果和预期结果之间设置一个容差 我已经证实 在实践中 使用双精度 在对最后两位有效小数进行四舍五入后 结果始终是正确的 但是usually四舍五入最后一位小数后
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db
  • Java中super关键字的范围和使用

    为什么无法使用 super 关键字访问父类变量 使用以下代码 输出为 feline cougar c c class Feline public String type f public Feline System out print fe

随机推荐

  • Linux 基础指令(1)

    导入 gt 在你的路径下 创建一个code目录文件夹 并cd进入这个目录 并在该目录下touch一个text txt的文件并显示当前自己所处的路径 目录 01 ls指令 02 pwd指令 03 cd指令 04 touch指令 05 mkdi
  • 解决Servlet中BeanUtils对象通过populate方法封装JSP提交的String数据与JavaBean数据类型不一致

    一 问题 在注册页面 JSP里面的表单提交给对应的Servlet默认是String类型 在使用BeanUtils populate方法封装相关数据至JavaBean时 由于JavaBean的数据格式不是String类型 从而导致报错 例如
  • Power BI 数据模型及核心概念介绍

    可视化图表的背后 数据模型 在Power BI中 每一个可视化图表背后 都是一个由许多数据表格组成的数据模型 这些框中包含数据表 且框内的每个行项都是一列 连接框的线表示表之间的关系 只有正确地将表格关联起来 才能实现各种可视化的效果 比如
  • 微软xp系统停止服务器,XP系统停止服务?其实微软留了一手

    离4月8日剩下不到50天 微软桌面产品Windows XP系统即将宣告退役 当大家都认为Windows XP已宣告死亡时 微软出面了 基于同内核的Windows XP Embedded嵌入版的扩展支持将延长至2019年 据外媒ZDNet网站
  • 获取GooglePlay下载来源广告数据统计接入同时analytics埋点

    获取GooglePlay下载来源广告数据 就是你的应用通过广告推广到各个渠道也就是代投 当用户点击这条广告之时 会跳转到Google Play的下载页面 Google Play会记录你是在哪个推广渠道跳转到Google Play的 当用户下
  • python常见的问题与解答:Python的Flask框架及Nginx实现静态文件访问限制功能

    本文来源于公众号 csdn2299 喜欢可以关注公众号 程序员学府 文章目录 Nginx配置 Flask 这篇文章主要介绍了Python的Flask框架及Nginx实现静态文件访问限制功能 Nginx方面利用到了自带的XSendfile 需
  • tf.reduce_mean()函数、reduction_indices参数介绍和示例以及tf.reduce_sum()、tf.reduce_max()系列函数介绍

    tf reduce mean 函数 reduction indices参数介绍和示例以及tf reduce sum tf reduce max 系列函数介绍 1 tf reduce mean input tensor axis None k
  • Java实现拖拽上传

    Java实现拖拽上传 本博文内容链接 1 CSDN地址 http blog csdn net u010506940 article details 43195939 2 51CTO地址 http 1936625305 blog 51cto
  • docker实战:dockerfile制作tomcat镜像

    1 准备镜像文件 tomcat压缩包 jdk的压缩包 下载tomcat我就不说了 下载JDK有很多版本 我们是在服务器centos上去用所以选择Linux版本 但是还会涉及到一个问题就是 选多少位的 我们这边可以用这个命令来看主机是多少位的
  • C++11之右值引用

    C 11之右值引用 传统的C 语法中就有引用的语法 而C 11中新增了的 右值引用 rvalue reference 语法特性 所以从现在开始我们之前学习的引用就叫做左值引用 lvalue reference 无论左值引用还是右值引用 都是
  • 东北大学c++实验第七周

    问题描述 分别声明Teacher 教师 类和Cadre 干部 类 采用多重继承方式由这两个类派生出新类Teacher Cadre 教师兼干部 类 要求 1 在两个基类中都包含姓名 年龄 性别 地址 电话等数据成员 2 在Teacher类中还
  • C++实现的自动构造LL(1)文法的first集、follow集和预测分析表。

    qquad 要求 程序识别的文法需是LL 1 文法 具体输入格式说明见initGrammer 本例采用的文法如下
  • 硬件工程师笔试题——21大疆秋招

    给志同道合者 成长的方向 鄙人不才 答案有误 三思 三思
  • Flask配置MySQL数据库使用

    文章目录 一 创建Flask 二 安装sqlalchemy 三 创建配置文件config py 四 绑定配置文件 参考资料 一 创建Flask pip install flask 成功安装之后app py如下所示 from flask im
  • python常用算法题-python基本算法题(一)

    1 3位水仙花数计算 3位水仙花数 是指一个三位整数 其各位数字的3次方和等于该数本身 例如 ABC是一个 3位水仙花数 则 A的3次方 B的3次方 C的3次方 ABC 使用Python 输出所有的3位水仙花数 gt gt gt for i
  • 匹配中文的正则表达式

    u4e00 u9fa5 匹配中文 匹配注释 不严密
  • hexo配置GitHub/gitee双部署

    我的博客主页 https qingmuzhang gitee io GitHub作为国外站点实在是比较慢也不太稳定 所以决定把博客搬到国内的gitee上 提高访问速度 gitee创建仓库 1 首先登录gitee https gitee co
  • matlab做三次拉格朗日插值多项式_拉格朗日插值法函数使用问题

    拉格朗日差值法 在数值分析中 拉格朗日插值法是以法国十八世纪数学家约瑟夫 拉格朗日命名的一种多项式插值方法 概念一般地 若已知 在互不相同 n 1 个点 处的函数值 即该函数过 这n 1个点 则可以考虑构造一个过这n 1 个点的 次数不超过
  • MLX90614红外温度计介绍

    MLX90614红外温度计简介 MLX90614是一款红外非接触温度计 TO 39金属封装里同时集成了红外感应热电堆探测器芯片和信号处理专用集成芯片 由于集成了低噪声放大器 17位模数转换器和强大的数字信号处理单元 使得高精度和高分辨度的温
  • 使用Stream流对集合排序

    文章目录 0 写在前面 1 格式 1 1 介绍 1 2 单个属性排序格式 1 3 多个属性排序格式 1 4 注意事项 2 代码举例 0 写在前面 有一些业务需要对集合按照一些规则进行排序 本篇介绍如何用Stream 对集合进行升序或者降序操