《第5章 函数式编程》节略部分
原创大约 2 分钟
流的筛选和切片操作。
// 筛选与切片
List<Integer> list1 = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
list1.stream().filter(i -> i < 3)
.distinct()
.skip(1)
.forEach(System.out::println);
所谓筛选即是过滤filter
,而切片则是将数据切分成一小份小一份
。
在上面的代码中,首先过滤出所有小于3的数值,然后去掉重复的数,再忽略数据流前面的第一个元素,并且将结果通过终端操作算子forEach()
打印出来。

在流操作中一个比较难理解的地方就是map
和flatMap
的区别。
// map:映射,把一种数据类型转换成另外一种数据类型
List<String> list2 = employees.stream()
.map(Employee::toString)
.collect(Collectors.toList());
// flatMap:扁平化映射
list2.add("hello world");
list2.add("hello china");
list2.stream().map(t -> t.split(" "))
.flatMap(Arrays::stream)
.distinct()
.forEach(System.out::println);
在map()
算子中,将员工对象Employee
转换成了一串人名列表。

而flatMap()
算子所谓的扁平化映射
的执行过程可以用下面的图来表示。

用一种比较形象的方式来描述它就是:flatMap()
算子是把禁锢数据的外层给压
平了,然后再执行映射。
上面的list2
中加入了hello world
和hello china
这两个字符串,通过map()
算子将它们拆分成了hello
、world
、hello
、china
这四个字符串。
然后flatMap()
又进一步将这四个字符串拆分成h
、e
、l
、l
、o
、w
、o
、r
、l
、d
、......等十几个字母字符串,再通过distinct()
算子去掉重复的内容,最后用forEach()
算子打印出结果。

流操作中另一个比较难于理解的就是归约reduce()
算子。
List<Integer> list3 = Arrays.asList(9, 7, 1, 5, 8, 10, 6);
Integer result = list3.stream()
.reduce(0, Integer::sum);
上面的代码将一组整数汇总求和。

reduce()
可以传入一个初始值,并在此数值的基础上累加,上面list3
中传入的是0。
除了这些基础的流计算之外,还有一些高级流计算,如分组和分区。但除了大数据应用之外,它们在普通应用中出现的频率并不高,而掌握了这些基础的算子,已经足以应对大部分的开发任务了。
感谢支持
更多内容,请移步《超级个体》。