栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 8 Stream讲解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 8 Stream讲解

Java 8 新特性 Stream流操作 我的理解
    在Java8中API新增了一个新的抽象称为流Stream,可以让我们通过声明的方式处理流Stream。我个人的理解是Stream流类似于SQL语句一样从数据库通过查询数据这种方式,将Java集合和表达进行抽象,以一种直观的方式展示出来。这个API通过干净、简洁以及高效率的代码提高Java程序员对数据的处理效率。

什么是Stream

通过这个单词的字面意思,可以知道它是流的意思,它是一个来自数据源的元素队列,且它支持类似SQL语句的聚合操作

元素 是某种类型的对象,形成一个队列,比如String类型的队列List,此时的元素就是String类型的元素,Java中的Stream不会对元素进行修改和存储,而是根据你的需求进行计算,如过滤,映射,去除,查找,匹配,排序。数据源 它可以使集合、数组等,它是流的来源。聚合操作 如上述所说的过滤,映射,去除,查找,匹配,排序等操作,类似SQL语句。流水线(Pipelining) 所有中间操作都会回到流本身,打个比方,流水线中一批产品需要通过不同的检查筛选,第一道操作之后剩下的产品进入第二道操作,之后最后的操作执行后剩下的产品就是想要的优质品。将多个操作串联成一个管道,类似fluent style。这样的话好处是可以对操作进行优化。内部迭代 没有Stream流之前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 而Stream提供了内部迭代的方式, 通过访问者模式实现。


如何生成流

在Java8中,有两个方法对集合接口进行生成流:

    Stream() 创建串行流parallelStream() 创建并行流
filter

filter 方法用于通过设置的条件过滤出元素。以下代码片段使用 filter 方法过滤空字符串:

List str = Arrays.asList("S","t","","r","e","a","m");
System.out.println("未通过Stream流操作的str:" + str);
List filter = str.stream().filter(s->!s.isEmpty()).collect(Collectors.toList());
System.out.println("通过Stream流操作的str:" + str);
System.out.println("通过Stream流操作返回的filter:" + filter);

该操作将str 中的空字符去除掉后将剩余的元素返回给filter中,并不会对原本的str进行操作。
输出结果

未通过Stream流操作的str:[S, t, , r, e, a, m]
通过Stream流操作的str:[S, t, , r, e, a, m]
通过Stream流操作返回的filter:[S, t, r, e, a, m]

进程已结束,退出代码为 0

forEach

在Stream中提供了forEach来迭代每个数据,以下代码使用forEach输出了从0到9中的10个随机数

Random random = new Random();
random.ints(0,10).limit(10).forEach(System.out::println);

定义一个Random对象,调用ints().limit(10)随机获取10个整数后进行输出。
输出结果

9
0
6
0
8
3
7
9
6
0

进程已结束,退出代码为 0


map

map 方法用于映射每个元素到对应的结果,以下代码使用map输出元素对应的平方数:

List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数并将重复的数据去除
List squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
System.out.println(squaresList);

通过map(i -> i*i )得到元素对应的平方数,并通过distinct()将重复的数据去除,最后通过collect()将数据返回。

输出结果:

[9, 4, 49, 25]

进程已结束,退出代码为 0

limit

limit 方法用于获取指定数量的流。 引用上面forEach代码片段使用 limit 方法打印出 10 条数据:

Random random = new Random();
random.ints(0,10).limit(10).forEach(System.out::println);

定义一个Random对象,调用ints().limit(10)随机获取10个整数后进行输出。
输出结果

9
0
6
0
8
3
7
9
6
0

进程已结束,退出代码为 0


sorted

sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的数字进行排序:

List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
numbers.stream().sorted().forEach(System.out::println);

通过调用stream().sorted()将numbers中的数据进行排序
输出结果

2
2
3
3
3
5
7

进程已结束,退出代码为 0

并行(parallel)程序

parallelStream 是流并行处理程序的代替方法。以下实例我们使用 parallelStream 来输出去除空字符串后的结果:

List strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
System.out.println("未通过Stream流操作的str:" + strings);
// 获取空字符串的数量
List filter = strings.parallelStream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("通过Stream流操作的str:" + strings);
System.out.println("通过Stream流操作返回的filter:" + filter);

输出结果:

未通过Stream流操作的strings:[abc, , bc, efg, abcd, , jkl]
通过Stream流操作的strings:[abc, , bc, efg, abcd, , jkl]
通过Stream流操作返回的filter:[abc, bc, efg, abcd, jkl]

进程已结束,退出代码为 0
Collectors

Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:

Liststrings = Arrays.asList("S", "", "t", "r", "e","a", "m","");
List filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining());
System.out.println("合并字符串: " + mergedString);

先通过filter 将空字符串去除,然后使用Collectors中的joining()将其合并成一个字符串。

筛选列表: [S, t, r, e, a, m]
合并字符串: Stream

进程已结束,退出代码为 0
统计

用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。

List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());

输出结果:

列表中最大的数 : 7
列表中最小的数 : 2
所有数之和 : 25
平均数 : 3.5714285714285716

进程已结束,退出代码为 0

以上例子参考菜鸟教程Java 8 Stream | 菜鸟教程加以修改

实际例子

统计学生的成绩,筛选出成绩大于60的学生,输出其名字和成绩(这里只是做例子所以名字直接使用数字代替,成绩使用random生成)

Random random = new Random();
List StuList = new ArrayList();
for(int i=0;i<20;i++) {
   Student s = new Student(String.valueOf(i),random.nextDouble()*100);
   StuList.add(s);
}
System.out.println("所有成绩:" + StuList.toString());
List collect = StuList.stream().filter(s -> s.grade > 60).collect(Collectors.toList());
System.out.println("筛选后的成绩:" + collect.toString());

先定义一个Random对象,用于生成成绩,通过循环创建20个Student类型的对象,名字使用循环的变量i进行代替,成绩通过random.nextDouble()进行生成,通过add()方法将对象添加进列表中,然后使用stream().filter()进行筛选出成绩大于60的学生并输出

所有成绩:[0 61.0, 1 59.4, 2 19.1, 3 2.2, 4 78.8, 5 69.7, 6 98.8, 7 3.1, 8 77.7, 9 35.9, 10 60.8, 11 95.4, 12 66.4, 13 76.9, 14 51.8, 15 87.0, 16 39.0, 17 80.7, 18 79.4, 19 81.0]
筛选后的成绩:[0 61.0, 4 78.8, 5 69.7, 6 98.8, 8 77.7, 10 60.8, 11 95.4, 12 66.4, 13 76.9, 15 87.0, 17 80.7, 18 79.4, 19 81.0]

进程已结束,退出代码为 0

总结

关于Stream流的内容就讲到这里了,通过Stream流我们可以写出更简洁高效的代码对这些数据进行处理,如过滤,映射,去除,查找,匹配,排序,不只是单一的操作,而是可以多个操作进行,得到我们所需要的数据,且不会对原数据进行操作,所以Stream流还是需要好好掌握的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/731389.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号