开篇介绍
Java 8 中新增的特性旨在帮助程序员写出更好的代码,其中对核心类库的改进是很关键的一部分,也是本章的主要内容。对核心类库的改进主要包括集合类的 API 和新引入的流(Stream),流使程序员得以站在更高的抽象层次上对集合进行操作。下面将介绍stream流的用法。
1.初始环境准备
? 场景:现在有一个公司,公司部门有一级部门,二级部门甲和二级部门乙(其中二级部门甲和二级部门乙是一级部门的子部门),
一级部门下面有有001号员工小明,二级部门甲下面有002号员工小刚和003号员工小李,二级部门乙有002号员工小刚和004号员工小张,其中员工id是唯一的,员工小刚既是二级部门甲又是二级部门乙的员工。代码展示如下:
public class LambdaUseCase {
static List<Department> departmentList;
static {
// 一级部门,部门人员有001号员工小明
Department departmentOne = new Department("一级部门", 1,10000L,11000L,
Arrays.asList(new Person("001","小明",22)));
// 二级部门甲,部门人员有002号员工小刚和003号员工小李
Department departmentTwoFirst = new Department("二级部门甲", 2,8000L,13000L,
Arrays.asList(new Person("002","小刚",23),
new Person("003","小李",32)));
// 二级部门乙,部门人员有002号员工小刚和004号员工小张
Department departmentTwoSecond = new Department("二级部门已", 2,7500L,15000L,
Arrays.asList(new Person("002","小刚",23),
new Person("004","小张",34)));
departmentList = Arrays.asList(departmentOne,departmentTwoFirst,departmentTwoSecond);
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Department {
// 部门名
private String departmentName;
// 部门等级
private Integer departmenRank;
// 部门薪资(单位分)
private Long departSalary;
// 部门日盈利
private Long departProfit;
// 部门人员集合
private List<Person> persons;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
//重写equal和hashcode方法,用于数据去重
@EqualsAndHashCode
class Person {
// 人员id
private String personId;
// 人员姓名
private String personName;
// 人员年龄
private Integer personAge;
}
2.创建流
单列集合: 集合对象.stream()
创建流
departmentList.stream();
数组:Arrays.stream(数组)
或者使用Stream.of
来创建
Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);
Stream<Integer> stream2 = Stream.of(arr);
Stream.of(1,2,3,4);
双列集合:转换成单列集合后再创建
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();
3.中间操作
3.1 map
如果有一个函数可以将一种类型的值转换成另外一种类型,map 操作就可以使用该函数,将一个流中的值转换成一个新的流
需求:公司今年收益提供,决定把所有部门的平均薪资提升1000。
List<Department> departments = departmentList.stream().map(e -> {
e.setDepartSalary(e.getDepartSalary() + 1000);
return e;
}).collect(Collectors.toList());
3.2 filter
对流中的元素进行过滤,筛选出符合过滤条件的数据
需求:需要筛选出部门平均薪资大于等于8000的数据。
List<Department> departments = departmentList.stream()
.filter(e -> e.getDepartSalary() >= 8000)
.collect(Collectors.toList());
3.3 flatMap
flatMap 方法可用 Stream 替换值,然后将多个 Stream 连接成一个 Stream
需求:把公司所有的人员收集到一个集合中。
不使用flatMap,你可能会这么做,循环里套循环,看上去不太美观。
Set<Person> personSet = new HashSet<>();
departmentList.stream().forEach(e->{
e.getPersons().stream().forEach(person->{
personSet.add(person);
});
});
使用flatMap写法。
Set<Person> personSet = departmentList.stream()
.flatMap(e -> e.getPersons().stream())
.collect(Collectors.toSet());
3.4 distinct
去除流中的重复元素
需求:将公司所有的人员统计出来,这回不使用Set去重,注意:002号员工即在二级部门甲又在二级部门乙
List<Person> personSet = departmentList.stream()
.flatMap(e -> e.