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