Java8新特性之Stream (2)

在介绍中间操作时,为了方便学习演示使用到了终端操作中的foreach方法,作用就和我们写的foreach循环类似,遍历执行,不返回值。

过滤filter // 过滤所有空字符串,注意是返回 true的留下 Stream.of("1", null, "2", "", "3") .filter(StringUtils::isNotEmpty) .forEach(System.out::print); 去重distinct // 去掉重复的2 Stream.of("1", "2", "2", "2", "3") .distinct() .forEach(System.out::print); 跳过skip // 跳过前两个元素 Stream.of("1", "2", "3", "4", "5") .skip(2) .forEach(System.out::print); 截短limit // 与skip相反,只留下前2个 Stream.of("1", "2", "3", "4", "5") .limit(2) .forEach(System.out::print); 映射map @Data @AllArgsConstructor public class Person { private String name; } // 将流中每个字符串转为Person实例 Stream.of("1", "2", "3") .map(Person::new) .forEach(System.out::print); // 将流每个字符串变成其长度,为了避免自动拆箱,使用mapToInt转为IntStream Stream.of("1", "2", "3") .mapToInt(String::length) .forEach(System.out::print); 扁平映射flatMap

用法和map类似,当我们需要把流中的每个元素全映射另外一个流,也就是数据在流中流里面,这时候操作就不方便,借助flatMap,我们可以把所有第二层流中的元素合并到最外层流

// 每个字符串按照逗号分隔合并成一个流 Stream.of("1,2,3", "4,5,6", "7,8,9") .flatMap(a -> Stream.of(a.split(","))) .forEach(System.out::print); 排序sorted Stream.of("4", "3", "5") .sorted() .forEach(System.out::print); Stream.of("4", "3", "5") .sorted(Comparator.naturalOrder()) .forEach(System.out::print); 并行流相关parallel,sequential,unordered // 串行流转并行流 Stream.of("1", "2", "3").parallel(); // 并行流转串行流 Arrays.asList("1", "2", "3").parallelStream().sequential(); // 在并行流中加上unordered,使得流变成无序,提供并行效率,此时limit相当于随机取2个元素 Arrays.asList("1", "2", "3", "4", "5") .parallelStream() .unordered() .limit(2).forEach(System.out::print); 调试peek

用于debug调试代码,在每次执行操作前,看一眼元素

// 每个元素会打印两遍 Stream.of("1", "2", "3").peek(System.out::print).forEach(System.out::print); 终端操作 遍历foreach Stream.of("1", "2", "3").forEach(System.out::print); // 并行流中使用用于保持有序 Arrays.asList("1", "2", "3").parallelStream().forEachOrdered(System.out::print); 通用统计count,max,min // 总个数,返回true|false Stream.of("1", "2", "3").count(); // 最大元素,返回Optional Stream.of("1", "2", "3").max(Comparator.naturalOrder()); // 最小元素,返回Optional Stream.of("1", "2", "3").min(Comparator.naturalOrder()); 数值流特有统计sum,average,summaryStatistics

以 IntStream 举例

// 累加求和 Stream.of("1", "2", "3").mapToInt(Integer::valueOf).sum(); // 求平均数 Stream.of("1", "2", "3").mapToInt(Integer::valueOf).average(); // 总和,最大值,最小值,平均数,总个数,应有尽有 Stream.of("1", "2", "3").mapToInt(Integer::valueOf).summaryStatistics(); 匹配match

返回true|false

// 是否有长度大于 2 的字符串 Stream.of("1", "22", "333").anyMatch(s -> s.length() > 2); // 是否一个长度大于 2 的字符串也没有 Stream.of("1", "22", "333").noneMatch(s -> s.length() > 2); // 是否字符串长度全大于 2 Stream.of("1", "22", "333").allMatch(s -> s.length() > 2); 查找find

由于是短路操作,所以只有在串行流中findAny和findFirst才区别明显

// 找到流中任意一个元素,普通流一般也返回第一个元素,并行流中返回任意元素 Stream.of("1", "22", "333").findAny(); // 找到流中第一个元素,普通流和并行流都一样 Stream.of("1", "22", "333").findFirst(); 汇总collect

把所有处理结果汇总,Collectors收集器里提供了很多常用的汇总操作

// 将结果汇总成一个list Stream.of("1", "22", "333").collect(Collectors.toList()); 归约reduce

谷歌著名的map-reduce理想,用于最后汇总结果

// 0作为起始的pre,流的结果等于pre乘以自身再加一,直到curr到达最后一个元素 // (1) pre = 0 curr = 1 计算 pre = 0 * 1 + 1 = 1 // (2) pre = 1 curr = 2 计算 pre = 1 * 2 + 1 = 3 // (3) pre = 3 curr = 3 计算 pre = 3 * 3 + 1 = 10 // (4) pre = 10 curr = null 返回结果 10 IntStream.of(1, 2, 3).reduce(0, (pre, curr) -> pre * curr + 1); // 当然如果不设置初始值,流中第一个元素就是pre IntStream.of(1, 2, 3).reduce((pre, curr) -> pre * curr + 1); 转数组toArray Stream.of("1", "22", "333").toArray(); 获得迭代器iterator Stream.of("1", "2", "3").iterator(); 获得并行可分迭代器spliterator Stream.of("1", "2", "3").spliterator(); 流类型判断isParallel Stream.of("1", "2", "3").isParallel(); 收集器进阶

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygjpd.html