Java8 常用的Stream流操作

来源:互联网 发布:学电脑编程 编辑:程序博客网 时间:2024/03/29 17:45

概念:Steam 是Java8 提出的一个新概念,不是输入输出的 Stream 流,而是一种用函数式编程方式在集合类上进行复杂操作的工具。简而言之,是以内部迭代的方式处理集合数据的操作,内部迭代可以将更多的控制权交给集合类。Stream 和 Iterator 的功能类似,只是 Iterator 是以外部迭代的形式处理集合数据的操作。

在Java8以前,对集合的操作需要写出处理的过程,如在集合中筛选出满足条件的数据,需要一 一遍历集合中的每个元素,再把每个元素逐一判断是否满足条件,最后将满足条件的元素保存返回。而Stream 对集合筛选的操作提供了一种更为便捷的操作,只需将实现函数接口的筛选条件作为参数传递进来,Stream会自行操作并将合适的元素同样以stream 的方式返回,最后进行接收即可。

2种操作:

1.intermediate  operation 中间操作:中间操作的结果是刻画、描述了一个Stream,并没有产生一个新集合,这种操作也叫做惰性求值方法。

2.terminal operation 终止操作:最终会从Stream中得到值。

如何区分这2种操作呢?可以根据操作的返回值类型判断,如果返回值是Stream,则该操作是中间操作,如果返回值是其他值或者为空,则该操作是终止操作。

如下图的前2个操作是中间操作,只有最后一个操作是终止操作。


可以形象地理解Stream的操作是对一组粗糙的工艺品原型(即对应的 Stream 数据源)进行加工成颜色统一的工艺品(即最终得到的结果),第一步筛选出合适的原型(即对应Stream的 filter 的方法),第二步将这些筛选出来的原型工艺品上色(对应Stream的map方法),第三步取下这些上好色的工艺品(即对应Stream的 collect(toList())方法)。在取下工艺品之前进行的操作都是中间操作,可以有多个或者0个中间操作,但每个Stream数据源只能有一次终止操作,否则程序会报错。

常用的 Stream 流操作:

1.collect(toList()) 终止操作

由Stream中的值生成一个List列表,也可用collect(toSet())生成一个Set集合。

例:取 Stream 中每个字符串并放入一个新的列表,

@Testpublic void collectToList() {String[] testStrings = { "java", "react", "angular", "vue" };List<String> list = Stream.of(testStrings).collect(Collectors.toList());for (int i = 0, length = list.size(); i < length; i++) {System.out.println(list.get(i));}}

2.map 中间操作

将一种类型的值映射为另一种类型的值,可以将 Stream 中的每个值都映射为一个新的值,最终转换为一个新的 Stream 流。


例:把 Stream 中每个字符串都转换为大写的形式,

@Testpublic void mapTest() {String[] testStrings = { "java", "react", "angular", "vue" };List<String> list = Stream.of(testStrings).map(test -> test.toUpperCase()).collect(Collectors.toList());list.forEach(test -> System.out.println(test));}
3.filter 中间操作

遍历并筛选出满足条件的元素形成一个新的 Stream 流。


例:筛选出以 j 字母开头的元素个数,此例中的count方法也是终止操作,是为了计算出 Stream 中的元素个数,

@Testpublic void filterTest() {List<String> list = Arrays.asList("java", "react", "angular", "javascript", "vue");long count = list.stream().filter(p -> p.startsWith("j")).count();System.out.println(count);}
4.flatMap 中间操作

可用 Stream 替换值,并将多个 Stream 流合并成一个 Stream 流。


例:将含有一串数字的两个流合并为一个流,

@Testpublic void flapMapTest() {List<Integer> list = (List<Integer>) Stream.of(Arrays.asList(1, 2, 3, 4, 5, 6), Arrays.asList(8, 9, 10, 11, 12)).flatMap(test -> test.stream()).collect(Collectors.toList());for (int i = 0, length = list.size(); i < length; i++) {System.out.println(list.get(i));}}
5.max 、min 终止操作

求 Stream 中的最大值、最小值。

例:取出 Stream 中最长的字符串

@Testpublic void maxTest() {String[] testStrings = { "java", "react", "angular", "javascript", "vue" };Optional<String> max = Stream.of(testStrings).max((p1, p2) -> Integer.compare(p1.length(), p2.length()));System.out.println(max);}
6.reduce 终止操作

从 Stream 的一组值中生成另一个值。


例:上述的max、min、count 实际上都是 reduce 操作,求出 Stream 元素数值的总和,

@Testpublic void reduceSumTest() {int sum = Stream.of(5, 6, 7, 8).reduce(0, (accumulator, element) -> accumulator + element);System.out.println(sum);}

reduce方法的第一个参数值 0 是初始值,第二个lambda表达式参数 (accumulator, element) -> accumulator + element 是执行求和操作,其中 accumulator 是累加器,element 是每次迭代的当前元素数值。

注意:Stream 流操作远不止以上介绍的几种,这里只介绍流操作的认识和几个简单实现,更多的流操作可查阅 API 官方文档,灵活结合 lambda 表达式和 Stream 操作可以更愉快地完成常见的集合操作。


原创粉丝点击