Stream API
TIP
Stream API 是 Java 8 引入的一套函数式数据处理工具,可以链式操作集合数据,让代码更加声明式和高效。
创建 Stream
java
// 从集合创建
Stream<String> stream1 = list.stream();
// 从数组创建
Stream<Integer> stream2 = Arrays.stream(new Integer[]{1, 2, 3});
// 使用 Stream.of
Stream<String> stream3 = Stream.of("A", "B", "C");
// 无限流
Stream<Integer> iterate = Stream.iterate(0, n -> n + 2).limit(10);中间操作
java
List<String> list = Arrays.asList("张三", "李四", "王五", "张三");
// filter - 过滤
list.stream()
.filter(s -> s.startsWith("张"))
.collect(Collectors.toList()); // [张三, 张三]
// map - 转换
list.stream()
.map(String::length)
.collect(Collectors.toList()); // [2, 2, 2, 2]
// distinct - 去重
list.stream()
.distinct()
.collect(Collectors.toList()); // [张三, 李四, 王五]
// sorted - 排序
list.stream()
.sorted()
.collect(Collectors.toList()); // [张三, 张三, 李四, 王五]终端操作
java
// forEach - 遍历
list.stream().forEach(System.out::println);
// collect - 收集
List<String> list = stream.collect(Collectors.toList());
Set<String> set = stream.collect(Collectors.toSet());
String joined = stream.collect(Collectors.joining(","));
// reduce - 规约
int sum = numbers.stream().reduce(0, Integer::sum);
// anyMatch / allMatch / noneMatch
boolean hasZhang = list.stream().anyMatch(s -> s.startsWith("张"));
boolean allLength2 = list.stream().allMatch(s -> s.length() == 2);实战示例
java
List<Student> students = getStudents();
// 找出成绩大于80分的前5个学生姓名
List<String> topStudents = students.stream()
.filter(s -> s.getScore() > 80)
.sorted(Comparator.comparing(Student::getScore).reversed())
.limit(5)
.map(Student::getName)
.collect(Collectors.toList());
// 按班级分组
Map<String, List<Student>> grouped = students.stream()
.collect(Collectors.groupingBy(Student::getClassName));
// 统计各班级平均分
Map<String, Double> avgScore = students.stream()
.collect(Collectors.groupingBy(
Student::getClassName,
Collectors.averagingDouble(Student::getScore)
));TIP
Stream 操作分为中间操作(Intermediate)和终端操作(Terminal)。中间操作是惰性的,只有遇到终端操作才会执行。