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

在这里插入图片描述

相关文章
|
3月前
|
索引
ES5常见的数组方法:forEach ,map ,filter ,some ,every ,reduce (除了forEach,其他都有回调,都有return)
ES5常见的数组方法:forEach ,map ,filter ,some ,every ,reduce (除了forEach,其他都有回调,都有return)
|
6月前
Stream之flatMap
Stream之flatMap
|
6月前
|
Java
java中Stream流中的forEach、filter、map、count、limit、skip、concat
java中Stream流中的forEach、filter、map、count、limit、skip、concat
238 0
|
7月前
|
前端开发 数据库
【Stream流】Sort排序详解
【Stream流】Sort排序详解
173 0
|
7月前
|
分布式计算 JavaScript 前端开发
Stream学习笔记(二)map与reduce
Stream学习笔记(二)map与reduce
|
7月前
使用Lamda表达式、stream流遍历Map、list
使用Lamda表达式、stream流遍历Map、list
124 0
|
7月前
|
Java
使用 stream 从 List 对象中获取某列数据
使用 stream 从 List 对象中获取某列数据
274 0
Stream方法使用-map与flatMap讲解
Stream方法使用-map与flatMap讲解
174 1
RxSwift操作符操作符map、flatMap、flatMapLatest、filter的使用与区别
RxSwift操作符操作符map、flatMap、flatMapLatest、filter的使用与区别
417 1
|
Java
Java集合Stream类filter的使用
Java集合Stream类filter的使用
149 0