本篇文章给大家带来的内容是关于java8中lambda和stream的详解(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
1. 前言
本文主要介绍Java8的2大主要新特性lambda表达式和Stream API,2者提供了更高层次的抽象,简化开发,提高生产效率。
2. Lambda表达式
2.1 初识Lambda表达式
立即学习“Java免费学习笔记(深入)”;
创建一个线程,使用了一个Runnable匿名内部类
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello Aron.");
}
});看着问题不大,实际上弊端挺明显:模板语法太多,真正有业务意义的的语句只有System.out.println("Hello Aron."),因为如此,也严重干扰了我们阅读代码。
引入lambda表达式后,则可以这么写
Thread thread = new Thread(() -> System.out.println("Hello Aron."));简洁了太多,有木有?
2.2 更多Lambda表达式
Runnable runnable = () -> System.out.println("Hello World.");
Consumer tConsumer = bean -> System.out.println("Hello World.");
Runnable runnable1 = () -> {
System.out.println("Hello World.");
System.out.println("Hello World.");
}; 语法分为3段式:参数 、-> 以及语句,即(...)-> { ...}
2.3 函数接口
Java是强类型语言,方法参数都有固定的类型。那么问题了,Lambda表达式,如果当做是一堆代码片段,也会表达一种明确的意图,这个意图,姑且可以理解为函数接口。
在编程过程中,总会遇到很多函数接口,以下是JDK中一些比较最重要的函数接口
接口参数返回类型示例
| 接口 | 参数 | 返回类型 | 示例 |
|---|---|---|---|
| Predicate |
T | boolean | 值等于“Hello”吗? |
| Consumer |
T | void | 输出一个值 |
| Function |
T | R | 获取对象的一个属性 |
| Supplier |
None | T | 工厂方法 |
| UnaryOperator |
T | T | 逻辑非(!) |
| BinaryOperator |
(T, T) | T | 求2个数的和(+) |
2.4 类型推断
先看一段熟悉的集合代码
ArrayListlist = new ArrayList<>();
在ArrayList
同理,在lambda表达式也是一样的。
BinaryOperatoraddLongs = (x, y) -> x + y;
在上面的表达 式中,我们注意到 (x, y)这里是没有申明方法的参数类型的,却能执行数学运算 +。
这里根据函数接口指定的泛型类为Long,即可推断方法的参数为Long,然后执行x + y。
2.5 Lambda小结
Lambda表达式是一个匿名方法,简化了匿名内部类的写法,把模板语法屏蔽,突出业务语句,传达的更像一种行为。
Lambda表达式是有类型的,JDK内置了众多函数接口
v1.8新增功能简介: 一、后台新增生成网站地图和生成Sitemap.xml的功能。 二、新增下载中心功能,可在后台上传doc,xls,ppt,rar,pdf文件。 三、新增产品缩略图自动缩放功能,图片按比例缩放,解决了图片变形问题。 四、新闻、产品详细页新增了上一个、下一个的功能,改善用户体验。 五、在线客服新增了阿里巴巴贸易通在线客服。 六、可在后台设置分享代码,如百度分享和AddThis等。
Lambda的3段式结构:(...)-> { ...}
3. Stream 流
3.1 简介
流(Stream)是Java8的新特性,是一种使程序员得以站在更高的抽象层次上对集合进行操作。在思路上,类似于SQL的存储过程,有几个步骤:
先定义一些操作的集合,注意:这里只定义,不真正执行
触发执行,获取结果
对结果进一步处理,筛选、打印、使用
其中,第1步的定义操作叫惰性求值,给你套路(返回Stream),但是不会执行返回结果。
第2步的触发操作叫及早求值,这个人说干就干,立马要结果(返回结果数据)。
第3步的筛选类似SQL的where子句,对结果进一步的筛选。
3.2 Stream API
Stream 类位于java.util.stream包,是Java8核心的类之一,拥有众多方法,下面罗列了一些比较重要的方法进行讲解。更多的是抛砖引玉,任何教程都比不上自己的悟性来得爽快,先找点感觉,先掌握基本用法尝试使用起来,慢慢自然就会了。
3.2.1 Stream.of(T… t)
要使用Stream,那就必须得先创建一个String类型的Stream
StreamStrStream = Stream.of("a", "b");
3.2.2 Stream.collect(Collector super T, A, R> collector)
使用收集器Collector将StrStream转化为熟悉的集合Collection
Listcollect = StrStream.collect(Collectors.toList());
3.2.2 Stream.map(Function super T, ? extends R> mapper)
所谓map,从字面理解就是映射。这里指的是对象关系的映射,
比如从对象集合映射到属性结合:
Listnames = Stream.of(new Student("zhangSan"), new Student("liSi")) .map(student -> student.getName()) .collect(toList());
从小写字母映射到大写字母:
Listcollected = Stream.of("a", "b", "hello") .map(string -> string.toUpperCase()) .collect(toList());
将 字符串流 根据空格分割成 字符串数组流
StreamstringStream = Stream.of("Hello Aron."); Stream stringArrayStream = stringStream.map(word -> word.split(" "));
3.2.3 Stream.filter(Predicate super T> predicate)
filter顾名思义,过滤筛选。这里的参数函数接口是一个条件,筛选出满足条件的元素
// 筛选年龄大于19的学生 Liststu = Stream.of(new Student("zhangSan", 19), new Student("liSi"), 20) .filter(student -> student.getAge() > 19) .collect(toList());
3.2.4 Stream.flatMap(Function super T, ? extends Stream extends R>> mapper)
flatMap扁平化映射,即将数据元素为数组的Stream转化为单个元素
StreamstringStream = Stream.of("Hello Aron."); // 返回值为数组 Stream stringArrayStream = stringStream.map(word -> word.split(" ")); // flatMap扁平化映射后,元素都合并了 Stream flatResult = stringArrayStream.flatMap(arr -> Arrays.stream(arr))
3.2.5 Stream.max(Comparator super T> comparator)
max即最大,类似SQL中的函数max(),从数据中根据一定的条件筛选出最值
// 筛选年龄最大/小的学生 StreamstudentStream = Stream.of(new Student("zhangSam", 19), new Student("liSi", 20)); Optional max = studentStream.max(Comparator.comparing(student -> student.getAge())); // Optional max = studentStream.min(Comparator.comparing(student -> student.getAge())); // 年龄最大/小的学生 Student student = max.get();
3.2.7 Sream.reduce(T identity, BinaryOperator binaryOperator)
reduce操作实现从一组值中生成一个值,上面的max、min实际上都是reduce操作。
参数Identity 表示初始值,
参数binaryOperator是一个函数接口,表示二元操作,可用于数学运算
// 使用reduce() 求和 (不推荐生产环境使用) int count = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);
上面代码,展开reduce() 操作
BinaryOperatoraccumulator = (acc, element) -> acc + element; int count = accumulator.apply( accumulator.apply(accumulator.apply(0, 1),2), 3);
3.2.8 综合操作
// 查找所有姓张的同学并按字典顺序排序,存储到list ListnewList = studentList.Stream() .filter(student -> student.getName().startsWith("张")) .sorted(Comparator.comparing(student -> student.getName()) .collect(toList());










