开发者社区> 养码青年> 正文

java8新特性(四)_Stream详解

简介: 之前写过一篇用stream处理map的文章,但是对stream没有一个整体的认识,这次结合并发编程网和ibm中介绍stream的文章进行一个总结,我会着重写对list的处理,毕竟实际工作中大家每天进行使用 Stream简单介绍 定义 A sequence of elements supporting sequential and parallel aggregate operations. 支持顺序并行聚合操作的元素序列 看看大神们怎么解读的 大家可以把Stream当成一个高级版本的Iterator。
+关注继续查看

之前写过一篇用stream处理map的文章,但是对stream没有一个整体的认识,这次结合并发编程网和ibm中介绍stream的文章进行一个总结,我会着重写对list的处理,毕竟实际工作中大家每天进行使用

Stream简单介绍

定义

  • A sequence of elements supporting sequential and parallel aggregate operations.

  • 支持顺序并行聚合操作的元素序列

看看大神们怎么解读的

大家可以把Stream当成一个高级版本的Iterator。原始版本的Iterator,用户只能一个一个的遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如“过滤掉长度大于10的字符串”、“获取每个字符串的首字母”等,具体这些操作如何应用到每个元素上,就给Stream就好了

简单demo

写一个过滤null的简单功能
    public static void main(String[] args) {

        List arrys = Arrays.asList(1, null, 3, 4);
        arrys.forEach(System.out::print);
        System.out.println();
        arrys = (List) arrys.stream()
                .filter(num -> num != null)
                .collect(Collectors.toList());
        arrys.forEach(System.out::print);

    }

执行结果

1null34
134
解析代码

img_816579e4cb3b72d6589afffaf8d129f2.png
1、 创建Stream;
2、 转换Stream(处理数据),每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换);
3、 对Stream进行聚合(Reduce)操作,获取想要的结果;

创建Stream

最常用的创建Stream有两种途径:

  • 通过Stream接口的静态工厂方法
  • 通过Collection接口的默认方法–stream(),把一个Collection对象转换成Stream(之前写的文章对于map的处理就是基于这个)
// 1. Individual values
Stream stream = Stream.of("a", "b", "c");
// 2. Arrays
String [] strArray = new String[] {"a", "b", "c"};
stream = Stream.of(strArray);
stream = Arrays.stream(strArray);
// 3. Collections(实际工作中经常用到)
List<String> list = Arrays.asList(strArray);
stream = list.stream();

转换Stream方法详解

这里其实是大家常用到的,着重讲解这里,这里的图片来自并发编程网,不得不佩服,程序写的好,画图也比我画的好

distinct

distinct: 对于Stream中包含的元素进行去重操作(去重逻辑依赖元素的equals方法),新生成的Stream中没有重复的元素;

示意图

img_7ab402185cf73cb7de61df2ce13fd290.jpe

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        list = list.stream()
                .distinct()
                .collect(Collectors.toList());
        list.forEach(System.out::print);

    }

结果

java---java---erlang---lua---lua---
java---erlang---lua---

filter

filter: 对于Stream中包含的元素使用给定的过滤函数进行过滤操作,新生成的Stream只包含符合条件的元素;

示意图

img_7e4f2635a9cc78b0be962f3fed2367ea.jpe

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        list = list.stream()
                .filter(e -> e.length() > 7)
                .collect(Collectors.toList());
        list.forEach(System.out::print);

    }

结果

java---java---erlang---lua---lua---
erlang---

map

map:它的作用就是把 input Stream 的每一个元素,映射成 output Stream 的另外一个元素。

示意图

T2PQJnXOJXXXXXXXXX_!!90219132.jpg

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        list = list.stream()
                .map(String::toUpperCase)
                .collect(Collectors.toList());
        list.forEach(System.out::print);

    }

结果

java---java---erlang---lua---lua---
JAVA---JAVA---ERLANG---LUA---LUA---

limit

limit: 对一个Stream进行截断操作,获取其前N个元素,如果原Stream中包含的元素个数小于N,那就获取其所有的元素;

示意图

img_34b157bfe63221fe7bc78c10605894db.jpe

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        list = list.stream()
                .limit(3)
                .collect(Collectors.toList());
        list.forEach(System.out::print);

    }

结果

java---java---erlang---lua---lua---
java---java---erlang---

skip

skip:返回一个丢弃原Stream的前N个元素后剩下元素组成的新Stream,如果原Stream中包含的元素个数小于N,那么返回空Stream;

示意图

img_34b157bfe63221fe7bc78c10605894db.jpe

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        list = list.stream()
                .skip(3)
                .collect(Collectors.toList());
        list.forEach(System.out::print);

    }

结果

java---java---erlang---lua---lua---
lua---lua---

findFirst

findFirst:它总是返回 Stream 的第一个元素,或者空。这里比较重点的是它的返回值类型:Optional

示意图

img_91cd7a90144999c7d95f7c9639c043f7.png

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        Optional<String> first = list.stream()
                .findFirst();

        System.out.println(first.get());

    }

结果

java---java---erlang---lua---lua---
java---

总结

当然,还有很多方法,这里不一一介绍,现实工作中使用常常结合起来

比如这段代码就是之前文章 过滤map 中 null值和空串的例子

public static Map<String, Object> parseMapForFilterByOptional(Map<String, Object> map) {

        return Optional.ofNullable(map).map(
                (v) -> {
                    Map params = v.entrySet().stream()
                            .filter((e) -> checkValue(e.getValue()))
                            .collect(Collectors.toMap(
                                    (e) -> (String) e.getKey(),
                                    (e) -> e.getValue()
                            ));

                    return params;
                }
        ).orElse(null);
    }

总之,Stream 的特性可以归纳为:

不是数据结构

  • 它没有内部存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据。
  • 它也绝不修改自己所封装的底层数据结构的数据。例如 Stream 的 filter 操作会产生一个不包含被过滤元素的新 Stream,而不是从 source 删除那些元素。
  • 所有 Stream 的操作必须以 lambda 表达式为参数

参考文章
-[1.]https://ifeve.com/stream/
-[2.]https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/

学习不是要么0分,要么100分的。80分是收获;60分是收获;20分也是收获。有收获最重要。但是因为着眼于自己的不完美,最终放弃了,那就是彻底的0分了。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java基础之Stream流(JDK1.8新特性)
JDK1.8 中增加了Stream流,Stream流是一个来自数据源的元素队列并支持聚合操作。 元素是特定类型的对象,形成一个队列,Java中的Stream并不会存储元素,而是按需计算 数据源是流的来源,可以使集合,数组,I/O channel,生成器generator等。 聚合操作类似SQL语句一样的操作,比如filter,map,reduce,match,sorted等
109 0
Java8 Stream,常用方法大合集
Java8 Stream,常用方法大合集
71 0
【Java8新特性】- Stream流
stream是java8新出的抽象概念,他可以让你根据你期望的方式来处理集合数据,能够轻松的执行复杂的查找、过滤和映射数据等操作。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
68 0
最强java8新特性-stream流
Java 8 是一个非常成功的版本,这个版本新增的Stream,配合同版本出现的Lambda ,给我们操作集合(Collection)提供了极大的便利。Stream流是JDK8新增的成员,允许以声明性方式处理数据集合,可以把Stream流看作是遍历数据集合的一个高级迭代器。Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找/筛选/过滤、排序、聚合和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供
152 0
Java核心技术之stream详解+Java8及以后的新特性
如何更好的使用Lambda表达式,优雅的使用Stream操作数据的切片、筛选、过滤,以及在大数据量下归类与计算利器Map/Reduce
203 0
一句话搞懂Java8 stream!!!
在review代码的过程中,经常看到一些代码能够使用stream的方式处理的更好,会建议同事使用stream。
62 0
Java8新特性之Stream流(基础篇)
前言 文本已收录至我的GitHub仓库,欢迎Star:github.com/bin39232820… 种一棵树最好的时间是十年前,其次是现在
71 0
Java8新特性之Stream流(高级篇)(上)
前言 文本已收录至我的GitHub仓库,欢迎Star:github.com/bin39232820… 种一棵树最好的时间是十年前,其次是现在
436 0
Java8新特性之Stream流(高级篇)(下)
前言 文本已收录至我的GitHub仓库,欢迎Star:github.com/bin39232820… 种一棵树最好的时间是十年前,其次是现在
66 0
Java 8 新特性:Java 类库的新特性之 Stream类(一)
Java 8 新特性:Java 类库的新特性之 Stream类(一)
155 0
+关注
养码青年
也许我注定成不了一个伟大的人 但是至少我可以做一个很棒的自己 正确认知自己,做好自己现在的工作 努力提升自己的能力 踏踏实实地做一个程序员!
文章
问答
视频
文章排行榜
最热
最新
相关课程
更多
相关电子书
更多
Java8简明教程
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
相关实验场景
更多