java8新特性(四)_Stream详解
之前写过一篇用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/
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java HashSet LinkedHashSet TreeSet类源码解析
Set集合中不含有重复的元素,插入重复的元素会失败。常用的有HashSet LinkedHashSet TreeSet。HashSet是无序的集合,LinkedHashSet中的排序和插入成功的顺序一致重复插入,TreeSet中元素是有序排列的,排序的依据是自身的comparator如果为null则根据key从小到大排序。HashSet和LinkedHashSet都是支持插入null的,TreeSet是否支持视comparator的情况,如果comparator不支持比较null的大小或者没有自定义的comparator则不支持插入null HashSet HashSet是基于HashMap实现的Set集合,所以支持插入null,但是不保持任何顺序。add成功时返回true,add已有元素时返回false。remove已有元素成功时返回true,remove不存在的元素时失败返回false。和HashMap一样是非线程安全类 public static void main(String args[]){ Set<String> set = new HashSet<&g...
- 下一篇
Springboot+ajax传输json数组以及单条数据的方法
Springboot+ajax传输json数组以及单条数据的方法 下面是用ajax传输到后台单条以及多条数据的解析的Demo: 结构图如下: image 下面是相关的代码: pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>springboot-ssm</artifactId> <ve...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS关闭SELinux安全模块
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2整合Redis,开启缓存,提高访问速度