使用Stream流对集合排序

简介: 有一些业务需要对集合按照一些规则进行排序,本篇介绍如何用Stream()对集合进行升序或者降序操作。之前只有接触过使用数据库进行排序,有一些情况需要不同的排序结果,如果进行多次查询会多次操作数据库,所以有些地方使用流对集合操作是更好的选择。Stream 流 -> 调用 sorted 方法 -> 方法内传入对比规则,用容器对象的属性作为入参作为排序依据,默认升序,需要倒叙的话后面调用.reversed() 方法。

@[TOC]

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);
    }
}

在这里插入图片描述

相关文章
|
机器学习/深度学习 Python
Scikit-Learn 高级教程——自定义评估器
Scikit-Learn 高级教程——自定义评估器【1月更文挑战第17篇】
282 1
vue3 表单中使用正则表达式
在Vue3中,可以使用正则表达式来验证表单输入字段的格式。以下是一个例子: 首先,定义一个正则表达式:
584 0
|
Java 数据库 Spring
java读取配置文件数据
java读取配置文件数据
414 0
|
SQL Java 数据库连接
mybatisplus QueryWrapper or写法
# MyBatis-Plus QueryWrapper的OR写法详解 MyBatis-Plus是一款基于MyBatis的增强工具,提供了丰富的简化操作,使开发者能更高效地进行数据库操作。`QueryWrapper`是MyBatis-Plus中用于构建查询条件的一个核心类,支持多种条件组合,包括AND和OR条件。本文将详细介绍如何使用 `QueryWrapper`实现OR条件的查询。 ## QueryWrapper简介 `QueryWrapper`用于构建动态SQL查询条件,它封装了各种条件构造方法,使得查询条件的构建更加简洁和直观。`QueryWrapper`中提供了丰富的方法来支持多
1268 0
|
人工智能 安全 Java
Java8 - LocalDateTime时间日期类使用详解
Java8 - LocalDateTime时间日期类使用详解
|
前端开发 数据安全/隐私保护
vue3表单参数校验+正则表达式
vue3表单参数校验+正则表达式
|
并行计算 Java API
|
SQL Java 数据库连接
Cause: java.sql.SQLException: Field ‘id‘ doesn‘t have a default value; Field ‘id‘ doesn‘t have a de
Cause: java.sql.SQLException: Field ‘id‘ doesn‘t have a default value; Field ‘id‘ doesn‘t have a de
|
小程序
基于微信小程序的电器维修系统设计与实现(源码+lw+部署文档+讲解等)
基于微信小程序的电器维修系统设计与实现(源码+lw+部署文档+讲解等)
298 0
基于微信小程序的电器维修系统设计与实现(源码+lw+部署文档+讲解等)
|
存储 搜索推荐 前端开发
智慧校园信息化管理系统的方案设计与实施
智慧校园信息化管理系统的方案设计与实施
656 0
智慧校园信息化管理系统的方案设计与实施