java8新特性stream深入解析
2019独角兽企业重金招聘Python工程师标准>>>
继续java8源码的发烧热,越看越是有充实的感觉。
数据时代下的产物
Java顺应时代的发展推出的高效处理大量数据能力的api,它专注于对集合对象进行各种非常便利、高效的聚合操作,借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,可以很方便地写出高性能的并发程序。
Stream可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
核心概念理解
一个流的操作 = 创建流 + 中间操作 + 结果转换。
- 创建流:指从集合转换过滤,数值转换过滤、I/O转换、创建等等;
- 中间操作:指对流中的数据进行聚合,如filter\map\sorted\reduce、distinct等等;
- 结果转换:指将流进行输出,打印、转换成array、转换成collection等;
Stream重要点:
- 流是不存储值的,只是一个管道过程
- 单个流只能被使用一次,再次被使用报错
- 流是支持函数式调用
测试样例定义
static List<ICar> cars = new ArrayList<>();static Map<Integer,String> kv = new HashMap<>();public static void init(){for(int i = 1; i <= 10; i++){WeiLaiCar car = new WeiLaiCar();car.setCarWheel(i);cars.add(car);kv.put(i,i+"-value");}
}
源码深度
在java.util.stream目录下可以看出有多种stream可以使用。Stream是支持泛型的对象的流,另外还提供了double\int\long常用数据类型的流,但他们提供的方法基本类似。
1、流是管道内部单向不可逆操作
Random random = new Random();
IntStream intStream = random.ints(10);
intStream.limit(6).forEach(PrintUtil::printTest);
intStream.toArray();
这里的第二个intStream.toArray()执行会报错误:IllegalStateException: stream has already been operated upon or closed
,流创建流到结束流单个管道内只能顺序一次使用,想要再次使用就得从源头重新创建流重新开始;
Random random = new Random();
IntStream intStream = random.ints(10);
intStream.limit(6).forEach(PrintUtil::printTest);
random.ints(15).toArray();
2、Stream的串行和并行
流的计算提供了两种模式:串行流和并行流,认是创建串行流。
- 提供流方法parallel()和sequential()在串并流间相互转换。
- 在Collection接口上添加了两个方法stream()\parallelStream(),parallel是并行计算的。这两个方法的内部实现皆是通过StreamSupport.stream(xx,aa)来实现,该方法的aa参数是boolean代表是否开启并行流;
3、collection与stream转换
流提供有方法toArray()转换成数组,也提供了方法collect()转换为list\set\Collection集合;同时Arrays.stream()方法可以把数组转换为流。
//list -> stream
Stream<ICar> carStream = cars.parallelStream();
carStream.filter(a -> a.getWheelCount() > 5).map(a-> a.hashCode()+"|"+a.getWheelCount()).forEach(PrintUtil::printTest);
//list转换为并发stream并打印符合条件的对象的hashcode和wheel数量:730140433|8//stream -> list
Stream<ICar> tmp = cars.stream();
List<ICar> carList = tmp.collect(Collectors.toList());
carList.forEach(PrintUtil::printTest);
//通过collect方法把stream转换为list并打印对象全称:com.ts.util.optional.WeiLaiCar@4e515669//array -> stream
ICar[] carss = {new WeiLaiCar(1),new WeiLaiCar(2)};
Arrays.stream(carss).filter(a -> a.getWheelCount() >2).forEach(PrintUtil::printTest);
//最终输出8个wheel大于2个的对象,并打印对象全称:com.ts.util.optional.WeiLaiCar@4dcbadb4//stream -> array
Object[] tmps = cars.stream().filter(a ->a.getWheelCount()>7).toArray();
PrintUtil.printTest(tmps.length);
//从cars中转换stream选出wheel大于7个的,转换为数值最终输出数量为:3
4、stream的排序
默认的排序要求排序对象是自然的有些值,一般dubble\int\long等;其他的类型需要主动定义comparator接口比较逻辑。
//默认sorted()要求是值natural order,即是自然顺序的
cars.stream().map(a->a.getWheelCount()).sorted().forEach(PrintUtil::printTest);
//先将对象的int类型的wheel聚合成集合,再使用默认排序(顺序)进行打印:1 2 3 4 5 6 ...10//自定义comparator,也可以在对象之间实现Comparator接口
cars.stream().sorted(Comparator.comparingInt(ICar::getWheelCount)).map(a->a.getWheelCount()).forEach(PrintUtil::printTest);
//自定义使用ICar的int类型wheel字段顺序比较,之后再将对象的wheel字段聚合进行打印:1 2 3 4 5 6 ...10
cars.stream().sorted(Comparator.comparingInt(ICar::getWheelCount).reversed()).map(a->a.getWheelCount()).forEach(PrintUtil::printTest);
//自定义使用ICar的int类型wheel字段顺序比较后再逆转,之后再将对象的wheel字段聚合进行打印
//与上面的顺序正好相反:10 9 8 7 ... 1
流包下重要的工具类
- Collectors 提供了很多 reduction 操作,都是静态的方法,如聚合成集合或者其他类型,官网例子如下:
// Accumulate names into a List
List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());// Accumulate names into a TreeSet
Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));// Convert elements to strings and concatenate them, separated by commas
String joined = things.stream().map(Object::toString).collect(Collectors.joining(", "));// Compute sum of salaries of employee
int total = employees.stream().collect(Collectors.summingInt(Employee::getSalary)));// Group employees by department
Map<Department, List<Employee>> byDept = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment));// Compute sum of salaries by department
Map<Department, Integer> totalByDept = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment,Collectors.summingInt(Employee::getSalary)));// Partition students into passing and failing
Map<Boolean, List<Student>> passingFailing = students.stream().collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
- StreamSupport 是stream的底层创建操作方法实现类,让我们查看一下Stream类的部分方法源码:
/*** Returns an empty sequential {@code Stream}.** @param <T> the type of stream elements* @return an empty sequential stream*/public static<T> Stream<T> empty() {return StreamSupport.stream(Spliterators.<T>emptySpliterator(), false);}/*** Returns a sequential {@code Stream} containing a single element.** @param t the single element* @param <T> the type of stream elements* @return a singleton sequential stream*/public static<T> Stream<T> of(T t) {return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);}
- 其他创建stream的方式,通过Stream的静态方法或者StreamSupport类:
Stream<String> stringStream = Stream.of("1","a","c");
stringStream.forEach(PrintUtil::printTest);
// 1 a cStream<Integer> integerStream = Stream.empty();
PrintUtil.printTest("count is " + integerStream.count());
//count is 0double[] tm = {22D,1.11D,33D,20.12D,11.02D,9.34D};
DoubleStream doubleStream = StreamSupport.doubleStream(Spliterators.spliterator(tm,0,5,1),true);
doubleStream.filter(a -> a < 20).forEach(PrintUtil::printTest);
//1.11 11.02
要主动拥抱新技术的出现
看着公司年轻的工程师一个比一个年轻,我变的更加努力了。要鞭策自己在项目中多尝试使用新API各种类和方法以锻炼自己,这些东西就是需要多用你才能发现区别并提升你的技术能力。
就算是写业务的也能写出不一样的水平。时常告诉自己去学习,追求进步不要做茫茫的小白。 对于一个工程师来说学习能力是你在这个行业必备的能力。
测试用例地址:play-java-sample
作者:Owen Jia
欢迎关注他的博客:Owen Blog
坚持写博客成了我的一种寄托
转载于:https://my.oschina.net/timestorm/blog/3009416
java8新特性stream深入解析相关推荐
- Java8新特性Stream流详解
陈老老老板 说明:新的专栏,本专栏专门讲Java8新特性,把平时遇到的问题与Java8的写法进行总结,需要注意的地方都标红了,一起加油. 本文是介绍Java8新特性Stream流常用方法超详细教学 说 ...
- java8新特性-stream对map集合进行过滤的方法
java8新特性-stream对map集合进行过滤的方法 stream对map集合进行过滤的方法
- List 集合去重方式与 java8新特性stream去重
以下介绍五种 - 不同的方法去除 Java 中 ArrayList 中的重复数据 1.使用 LinkedHashSet 删除 arraylist 中的重复数据 LinkedHashSet 是在一个 A ...
- java8新特性stream流
参考自深蓝至尊的Java8 新特性之流式数据处理 一. 流式处理简介 在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式 ...
- java8新特性-Stream入门学习
上一篇介绍了Lambda的学习,如果对Lambda表达式还不清晰的同学可以戳一下这个链接:java8新特性-lambda表达式入门学习.java8除了提供了Lambda表达式,操作集合的Stream ...
- Java8新特性 - Stream - 13 - Stream的max()、min()方法详解
1.方法介绍 [方法签名]1.Optional<T> max(Comparator<? super T> comparator);2.Optional<T> min ...
- 【Stream】java8新特性Stream流总结
一.什么是stream 在 java8 中增加了一个新的抽象接口 Stream API,使用 Stream 操作集合类似于使用 SQL 语句数据库查找数据类似,提供直观的方法进行操作. Stream ...
- 夯实基础,Java8新特性Stream详细教程
1 基本特性 Java8的API中添加了一个新的特性: 流,即stream.stream是将数组或者集合的元素视为流,流在管道中流动过程中,对数据进行筛选.排序和其他操作. 1.1 流的特性 stre ...
- java8新特性-stream学习
java8除了提供了Lambda表达式,操作集合的Stream API也是新特性中最值得学习和掌握的,它大大简化了,我们操作数据集合的代码量的书写.简单来说Stream是一个抽象概念,可以通过查找,过 ...
最新文章
- python3.7装anaconda什么版本_【对话系统】配置python+dlatk+theano不装anaconda的血泪史...
- rdd分组聚合算子xxByKey,xxBy
- Rsync服务及搭建备份服务器
- php study 后门,phpStudy后门简要分析
- java excel 2007兼容包_office2007兼容包
- 365锦鲤助手修改版,砍价小程序
- 如何制作图书专用标签
- openwrt配置内核,加载air720 4G模块的USB串口设备
- java 图片清晰度_Java 图片处理——如何生成高清晰度而占有磁盘小的缩略图
- Flex Builder中网络监视器导致“访问URL时遇到安全性错误”
- 思科防火墙解析(ASA)
- Dynamic ODT
- IOS-APP自动化打包上传蒲公英Shell版
- 浏览器实现抓包过程详解
- matlab读取心电注释.qrs文件格式,MIT-BIH ECG 心电数据的下载和读取图解 - 晨宇思远 - CSDN博客...
- 【软件设计师】知识点与试题
- 今天,洋哥北漂整整11年
- python模拟银行存取款_python 简单模拟银行转账功能
- 报考报名显示服务器已满,广东教师资格证报名考区已满怎么办
- 中国电信2015年的三张底牌
热门文章
- openldap linux客户端,OpenLDAP 客户端安装部署
- java接口开发 全局异常,全局异常处理
- r数据框计算字符出现次数_R语言系列第二期:①R变量、脚本、作图等模块介绍...
- python实现链表的删除_Python垃圾回收机制
- Filter案例之登录验证
- 博客园自动添加版权说明,自动添加文章链接
- luogu4267 TamingtheHerd (dp)
- 排序算法杂谈(三) —— 归并排序的非递归实现
- MySQL约束和修改数据表知识集结
- Php Laravel框架 多表关系处理 之 Eloquent一对多关系处理