之前写过一篇用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
解析代码


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中没有重复的元素;

示意图

代码演示
    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只包含符合条件的元素;

示意图

代码演示
    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 的另外一个元素。

示意图

代码演示
    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,那就获取其所有的元素;

示意图

代码演示
    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;

示意图

代码演示
    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

示意图

代码演示
    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分了。

java8新特性(四)_Stream详解相关推荐

  1. 【java8新特性】——Optional详解(三)

    一.简介 Optional类是Java8为了解决null值判断问题,借鉴google guava类库的Optional类而引入的一个同名Optional类,使用Optional类可以避免显式的null ...

  2. Java8新特性Stream流详解

    陈老老老板 说明:新的专栏,本专栏专门讲Java8新特性,把平时遇到的问题与Java8的写法进行总结,需要注意的地方都标红了,一起加油. 本文是介绍Java8新特性Stream流常用方法超详细教学 说 ...

  3. java lambda表达式详解_Java8新特性Lambda表达式详解

    课程目标: 通过本课程的学习,详细掌握Java8新特性之Lambda表达式: 适用人群:有Java基础的开发人员: 课程概述:从Java 8出现以来lambda是最重要的特性之一,它可以让我们用简洁流 ...

  4. H5的新特性及API详解(很惊人)

    H5的新特性及API详解(很惊人) 2017-01-20 17:00 4057人阅读 评论(0) 收藏 举报  分类: h5(11)  js函数(64)  js技巧(15)  版权声明:本文为博主原创 ...

  5. 显微镜下的webpack4的新特性:mode详解

    webpack4支持的一个新特性就是zero配置,不需要config,也可以打包,这对于懒癌患者很有诱惑力,但是这也意味着我们不清楚零配置发生了写什么,也不知道打包出来的文件是否符合我们的心意,全部都 ...

  6. jdk8新特性 lambda表达式详解

    本文主要讲到的内容有: 一- 前言 二- 背景 三- lambda表达式的语法 四- Lambda程序例子 4-1 Runnable Lambda 4-2 Comparator Lambda 4-3 ...

  7. C++11中的一些新特性以及代码详解

    C++11新特性 auto decltype 追踪返回类型 类内成员初始化 列表初始化 基于范围的for循环 静态断言 noexcept修饰符 强类型枚举 常量表达式 原生字符串字面值 继承控制 fi ...

  8. C++11新特性——λ(lambda)表达式详解

    C++11新特性--λ(lambda)表达式 C++11中引入了λ表达式,它可以用来定义一个内联(inline)的函数,作为一个本地的对象或者一个参数.有了λ表达式,我们可以很方便的使用stl标准库. ...

  9. JAVA8 Optional新特性和使用详解

    文章目录 一.Optional简介 二.应用Optional 1.创建Optional对象 2.Optional中map用法 3.Optional其它方法用法 三.Optional实战 1.创建Opt ...

  10. 重学Java8新特性(四) : 日期时间API、LocalDateTime、DateTimeFormatter、开发中时间工具类(常用)

    文章目录 一.JDK8中日期时间API的介绍 1.1.LocalDate.LocalTime.LocalDateTime的使用 2.2.Instant类的使用 2.3.DateTimeFormatte ...

最新文章

  1. 不是都需要ARM吗?
  2. 各浏览器对document.getElementById等方法的实现差异
  3. SQL中cross join,left join,right join ,full join,inner join 的区别
  4. 使用Project Jigsaw的JDK 9 Early Access上的Eclipse IDE
  5. 云计算时代下的数据中心运维之路
  6. USACO-Section1.5 Arithmetic Progressions(枚举)
  7. Python自动绘制UML类图、函数调用图(Call Graph)
  8. django 更改默认数据库为MySQL
  9. linux网络系统调用,Linux网络系统调用接口--待续
  10. Java 数组类型转字符串类型
  11. 如何下载谷歌地图高程数据
  12. 人工智能电力行业应用,人工智能的需求分析
  13. rk3399_9.0.1_mid 时区转换
  14. 利用计算机对多媒体进行综合处理,多媒体技术复习题及答案
  15. 客户端软件GUI开发技术漫谈:原生与跨平台解决方案分析
  16. VMware虚拟机配置IP地址
  17. R语言命令行写linux,如何在Linux上编写和使用R脚本
  18. 随机数的产生原理与实现
  19. 计算机技术复试面试英语自我介绍,计算机复试英语自我介绍
  20. C语言——小白鼠排队

热门文章

  1. 一次Binder通信最大可以传输多大的数据?
  2. 第三周项目四-穷举法解决组合问题(1)
  3. 计算机dns没有响应如何解决方案,dns未响应如何解决 dns未响应解决方法【图文】...
  4. sonar:查询全部项目的bug和漏洞总数(只查询阻断/严重/主要级别)
  5. css3 @keyframes、transform详解与实例
  6. 20165235实验四 Android程序设计
  7. 什么是SCADA Viewer
  8. 第三方登录 (faceBook )
  9. 免安装版的MySQL的安装与配置
  10. AndroidStudio(1 下载安装,环境搭建,使用设置)