java8 新特性入门 stream/lambda
Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势
Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。获取一个数据源(source)→ 数据转换→执行操作获取想要的结果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道
为什么不在集合类实现这些操作,而是定义了全新的Stream API?Oracle官方给出了几个重要原因:
一是集合类持有的所有元素都是存储在内存中的,非常巨大的集合类会占用大量的内存,而Stream的元素却是在访问的时候才被计算出来,这种“延迟计算”的特性有点类似Clojure的lazy-seq,占用内存很少。
二是集合类的迭代逻辑是调用者负责,通常是for循环,而Stream的迭代是隐含在对Stream的各种操作中,例如map()。
对于基本数值型,目前有三种对应的包装类型 Stream:IntStream、LongStream、DoubleStream。
stream是Java8新增的一大API。官方定义:支持在元素流上支持功能式操作,例如映射减少集合上的转换。
特点:
不储存。数据流不是存储元素的数据结构;相反,它将元素从源数据结构、数组、生成器函数或输入/输出通道传递到计算操作的管道中。
功能性。一个流操作产生一个结果,但不修改它的源。例如,从一个集合中过滤得到的数据流产生一个新的流,而不过滤元素,而不是从源集合中移除元素。
懒惰寻求。许多流操作,如过滤、映射,或去除重复,可以懒洋洋地,暴露的机会,优化。例如,“寻找三个连续的元音字母的第一个字符串”不需要检查所有的输入字符串。流操作分为中间(流生产)操作和终端(价值或副作用生产)操作。中间操作总是懒惰。
可能无界。虽然集合有一个有限的大小,流不需要。短路操作如极限(n)或findfirst()可以允许无限流计算在有限的时间内完成.
意为流但与I/O流又有所不同。Stream
是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate
operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda
表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join
并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错,
但使用 Stream API 无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。所以说,Java 8 中首次出现的
java.util.stream 是一个函数式语言+多核时代综合影响的产物。
Lambda语法:
(params) -> expression
(params) -> statement
(params) -> { statements }
关键字:
filter:是一个中间操作,接受一个predicate接口类型的变量,并将所有流对象中的元素进行过滤。filter(s -> s.getState()==State.pay)
map:是一个对于流对象的中间操作,通过给定的方法,它能够把流对象中的每一个元素对应到另外一个对象上。map(s ->
s.getPlanNo()) / map(s -> Plan::planNo) / 价格变成 10倍 map(s ->
s.getPrice().multiply(BigDecimal.valueOf(10)))
reduce:把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),返回单个的结果值,并且reduce操作每处理一个元素总是创建一个新值
BigDecimal total = stream().reduce(BigDecimal.zero, (a,b) -> a.add(b)); 或
BigDecimal total = stream().reduce(BigDecimal.ZERO, BigDecimal::add)
limit : 返回 Stream 的前面 n 个元素;skip 则是扔掉前 n 个元素
sorted: 一个中间操作,能够返回一个排过序的流对象的视图。流对象中的元素会默认按照自然顺序进行排序,除非你自己指定一个Comparator接口来改变排序规则.
collect: 修改现存的值
Collectors 类的主要作用就是辅助进行各类有用的 reduction 操作
groupingBy 按规则分组:stream().collect(Collectors.groupingBy(p->p.getState()))
partitioningBy 是一种特殊的 groupingBy,它依照条件测试的是否两种结果来构造返回的数据结构,get(true) 和 get(false) 能即为全部的元素对象。
Stream 有三个 match 方法,从语义上说:
allMatch:Stream 中全部元素符合传入的 predicate,返回 true
anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true
noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true
示例,domain
public class Plan {
private int id;
private String planNo;
private BigDecimal price;
private long total;
private State state;
private Calendar createTime;
private JSONObject features = new JSONObject();
Sate :noPay(1,"未支付"), pay(2,"支付"), settle(3,"结算"),
List<Plan> planList = initList();
1. 把方案编号planNo转换大写 返回列表
List<String> noList = planList.stream().map(p->p.getPlanNo().toUpperCase()).collect(Collectors.toList());
2,价格由高到低排序
List<Plan> list = planList.stream().sorted((a,b) -> b.getPrice().compareTo(a.getPrice())).collect(Collectors.toList());
3,状态为支付的价格由高到低排序
planList.stream().filter(s -> State.pay ==
s.getState()).sorted((a,b) ->
b.getPrice().compareTo(a.getPrice())).collect(Collectors.toList());
4,求最高价/最低价/总价, total数量平均,总和
BigDecimal max = planList.stream().max((a,b)->a.getPrice().compareTo(b.getPrice())).get().getPrice();
BigDecimal min = planList.stream().min((a,b)->a.getPrice().compareTo(b.getPrice())).get().getPrice();
BigDecimal total = planList.stream().map(p->p.getPrice()).reduce(BigDecimal.ZERO,(a,b)->a.add(b));
平均 : planList.stream().mapToLong(Plan::getTotal).average().getAsDouble();
总和:planList.stream().mapToLong(Plan::getTotal).sum()
5,总共有多少种状态值
long count = planList.stream().map(p->p.getState()).distinct().count();
long c2 = planList.stream().map(p->p.getState()).collect(Collectors.toSet()).size();
6,方案编号中包含某些字符
List<Plan> list = planList.stream().filter(p->p.getPlanNo().contains("gt")).collect(Collectors.toList());
7,价格前三的方案
List<Plan> topList =
planList.stream().sorted((a,b)->b.getPrice().compareTo(a.getPrice())).limit(3).collect(Collectors.toList());
8,按方案状态分组列表
Map<State, List<Plan>> map = planList.stream().collect(Collectors.groupingBy(p->p.getState()));
9,方案分成是否支付二种,查询列表
Map<Boolean, List<Plan>> map =
planList.stream().collect(Collectors.partitioningBy(s ->
s.getState()==State.noPay));
map.get(true) 是全部 未支付
map.get(false) 是支付 和 结算
10,转换成Map结构 <方案编号 , 价格>
Map<String, BigDecimal> map = planList.stream().collect(Collectors.toMap(p->p.getPlanNo(), Plan::getPrice));
11,转换数据结构 , list转成数组
Plan[] ps = planList.stream().toArray(Plan[]::new);
12,按状态算数量的总和/平均数
平均:Map<State, Double> map =
planList.stream().collect(Collectors.groupingBy(Plan::getState,
Collectors.averagingLong(Plan::getTotal)));
求和:Map<State, Long> sum =
planList.stream().collect(Collectors.groupingBy(Plan::getState,
Collectors.summingLong(Plan::getTotal)));
Map<State, LongSummaryStatistics> sumMap =
planList.stream().collect(Collectors.groupingBy(Plan::getState,
Collectors.summarizingLong(Plan::getTotal)));
LongSummaryStatistics描述流中元素的各种摘要数据,求 count, min, max, sum, and average.
java8 新特性入门 stream/lambda的更多相关文章
- 乐字节-Java8新特性之Stream流(上)
上一篇文章,小乐给大家介绍了<Java8新特性之方法引用>,下面接下来小乐将会给大家介绍Java8新特性之Stream,称之为流,本篇文章为上半部分. 1.什么是流? Java Se中对于 ...
- Java8 新特性之Stream API
1. Stream 概述 Stream 是Java8中处理集合的关键抽象概念,可以对集合执行非常复杂的查找,过滤和映射数据等操作; 使用 Stream API 对集合数据进行操作,就类似于使用 SQL ...
- 【Java8新特性】Stream API有哪些中间操作?看完你也可以吊打面试官!!
写在前面 在上一篇<[Java8新特性]面试官问我:Java8中创建Stream流有哪几种方式?>中,一名读者去面试被面试官暴虐!归根结底,那哥儿们还是对Java8的新特性不是很了解呀!那 ...
- 【Java8新特性】- Stream流
Java8新特性 - Stream流的应用 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! ...
- java8新特性-入门摘要
本文是针对java8做的入门摘要笔录,详细分析可参见如下原文. 原文地址 http://www.javacodegeeks.com/2013/02/java-8-from-permgen-to-met ...
- Java8新特性之Stream
原文链接:http://ifeve.com/stream/ Java8初体验(二)Stream语法详解 感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com上篇文章Java8初体验( ...
- Java8新特性--流(Stream)
1.简介 Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性.在本文中我们一起来学习引入的一个新特性- ...
- java8新特性五-Stream
继上次学习过Java8中的非常重要的Lambda表达式之后,接下来就要学习另一个也比较重要的知识啦,也就如标题所示:Stream,而它的学习是完全依赖于之前学习的Lambda表达式. Java 8 A ...
- Java8新特性之一:Lambda表达式
Java8是自java5之后最重大的一次更新,它给JAVA语言带来了很多新的特性(包括编译器.类库.工具类.JVM等),其中最重要的升级是它给我们带来了Lambda表达式和Stream API. 1. ...
随机推荐
- StackExchange.Redis学习笔记(三) 数据库及密码配置 GetServer函数
这一章主要写一些StackExchange.Redis的配置及不太经常用到的函数 数据库连接 下面是我的连接字符串,里面指定了地址,密码,及默认的数据库 Redis启动后默认会分成0-15个数据库,不 ...
- 利用可变参数模拟Printf()函数实现一个my_print()函数和调用可变参数注意的陷阱!
可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 例如,对于函数: void test(char a ...
- Sublime Text 3 修改配色方案
你可能会觉得 Sublime Text 配色方案的颜色(注释.背景色)看起来不习惯,其他都满意.此时我们可以自己修改这些配色,不需要更换整个配色方案. 需要安装 PackageResourceView ...
- mysql步骤详解
一.配置MySQL数据库 1.解压绿色版mysql,并改名为mysql5.7,如下图 对比一下下图5.6以前的版本,少data目录(存放数据)和my-default.ini文件(配置信息) 二.安装服 ...
- Geth控制台使用及Web3.js使用实战
在开发以太坊去中心化应用,免不了和以太坊进行交互,那就离不开Web3. Geth 控制台(REPL)实现了所有的web3 API及Admin API, 使用好 Geth 就是必修课.结合Geth命令用 ...
- 网络分析法(Analytic Network Process,ANP)
什么是网络分析法 网络分析法(ANP)是美国匹兹堡大学的T.L.Saaty教授于1996年提出的一种适应非独立的递阶层次结构的决策方法,它是在层次分析法(Analytic Hierarchy Proc ...
- 软件测试管理QC
一.QC简介 1)是HP公司的产品,是B/S结构的产品 2)在QC服务器中,打开IE浏览器,在地址栏中输入QC服务器的网址或者IP地址. 查看虚拟机的IP地址: 本地连接-属性-TCP/IP协议(重点 ...
- MySQL修改表
一.给表mytablename添加新字段newcolumn alter table mytablename add newcolumn varchar(50) COMMENT '新字段备注信息' 二. ...
- 用swoole和websocket开发简单聊天室
首先,我想说下写代码的一些习惯,第一,任何可配置的参数或变量都要写到一个config文件中.第二,代码中一定要有日志记录和完善的报错并记录报错.言归正传,swoole应该是每个phper必须要了解的, ...
- HDU 1014 Uniform Generator 欧几里得
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1014 解题思路: 1. 把题目意思读懂后,明白会输入两个数,然后根据题中的公式产生一系列伪随机数,看这 ...