5分钟上手Java8新特性Stream流的使用
1. 为什么使用Stream流操作?
Stream 作为 Java 8 的一大亮点,Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。
Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。
Java 8 中首次出现的 java.util.stream 是一个函数式语言+多核时代综合影响的产物。
2. 实战准备
1. Entity的定义
- 我们使用lombok的 @Data 注解来解决pojo类的“样板式代码”,如getter,setter,equals方法等。
- 而@Builder注解的作用是启用创建者模式,也就是说在其他类中调用我们的Student类的时候使用 类名.builder()的方式构造对象,而不能直接声明构造对象。
import lombok.Builder;
import lombok.Data;
@Data
// 建造者模式创建对象
@Builder
public class Student {
private Long id;
private String name;
private int age;
private double score;
}
2. 建造者模式创建对象
- 我们使用Student.builder()新建对象,原因是为了创建复杂对象的算法,并且独立于该对象的组成部分以及它们的装配方式的设计模式。
- 我们构建了三个学生对象 分别是 小白 20岁 10.1分…
List<Student> resultList = new ArrayList<>();
resultList.add(Student.builder().id(1L).name("小白")age(20).score(10.1).build());
resultList.add(Student.builder().id(2L).name("小红").age(31).score(9.6).build());
resultList.add(Student.builder().id(3L).name("小黄").age(16).score(5.9).build());
3. 几种使用方法介绍
1. 根据某个属性进行筛选
- 根据某个属性进行分组
List<String>nameList=list.stream().map(Student::getName).collect(Collectors.toList());
- 可以看到我们将原本的对象集合List,使用map作为类型转换的工具,也就是 <Key,Value>的形式,对每个学生对象对应着一个年理进行分组,然后使用stream流的收集器collect将获得的map中的姓名元素作为一个List集合进行回收整理。
- 得到结果如下
nameList:[小白, 小红, 小黄]
2. 根据某个属性进行筛选
List<Student> highCoreList = list.stream().filter(bean -> bean.getScore() > 5.0).collect(Collectors.toList());
- 这里我们的操作是使用stream流操作中的filter进行条件过滤 ,bean作为我们要遍历筛选的对象的代表,不难看出我们这里的分数筛选条件是>5.9分,那么经过操作,我们可以得到List结果集如下。
highCoreList:[Student(id=1, name=小白, age=20, score=10.1), Student(id=2, name=小红, age=31, score=9.6)]
3. 根据某个元素进行排序
List<Student> sortList = list.stream().sorted((a, b) -> b.getAge() - a.getAge()).collect(Collectors.toList());
- 我们通过stream流中的sorted方法对对象根据年龄排序,若以sorted(a,b)为例,那么操作如下。
- 逆序:使用b.getAge() - a.getAge()
- 顺序:使用a.getAge() - b.getAge()
4. List转Map
Map<Long, Student> idMap = list.stream().collect(Collectors.toMap(Student::getId, bean -> bean));
- 根据id为key,bean对应的对象为value 使用toMap方法进行转化,得到map<Long,Studeng>,得到输出结果如下。
idMap:{1=Student(id=1, name=小白, age=20, area=A, score=10.1),
2=Student(id=2, name=小红, age=31, area=A, score=9.6),
3=Student(id=3, name=小黄, age=16, area=B, score=5.9), }
5. Map排序
Map<Long, Integer> idMap = list.stream().collect(Collectors.toMap(Student::getId, Studnet::getAge, (value1, value2) -> value1));
Map<Long, Integer> sortedKeyMap = idMap.entrySet().stream()
.sorted(Map.Entry.<Long, Integer>comparingByKey().reversed())
.collect(
Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(oldVal, newVal) -> oldVal,
LinkedHashMap::new
)
);
- 这里我们首先结局key重复元素的问题,我们可以看到,进行数据收集的时候,我们使用了id和age两个属性,那么我们使用 (value1, value2) -> value1),目的是 使用一个合并函数来决定如何合并相同key的值。
- 其次,我们利用comparingByKey()达到按Key排序的目的,同理可知用comparingByValue进行按value排序。
- 最后使用reversed()函数进行map内元素倒序。