This article brings you a detailed explanation of Lambda and Stream in Java8 (with code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
1. Preface
This article mainly introduces the two main new features of Java8, lambda expression and Stream API. The two provide a higher level of abstraction and simplify development. ,Increase productivity.
2. Lambda expression
2.1 First introduction to Lambda expression
Create a thread and use an Runnable
anonymous The internal class
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello Aron.");
}
});
Copy after login
may not seem like a big problem, but in fact the disadvantages are quite obvious: there are too many template syntaxes, and the only statements that really have business significance are System.out.println("Hello Aron.")
, because of this, also seriously interferes with our reading of the code.
After introducing lambda expression, you can write like this
Thread thread = new Thread(() -> System.out.println("Hello Aron."));
Copy after login
It’s too concise, is there any idea?
2.2 More Lambda expressions
Runnable runnable = () -> System.out.println("Hello World.");
Consumer<T> tConsumer = bean -> System.out.println("Hello World.");
Runnable runnable1 = () -> {
System.out.println("Hello World.");
System.out.println("Hello World.");
};
Copy after login
The syntax is divided into 3 sections: parameters, ->
and statements, that is, (...)- > { ...}
2.3 Function interface
Java is a strongly typed language, and method parameters have fixed types. So here’s the problem. Lambda expressions, if regarded as a bunch of code fragments, will also express a clear intention. This intention can be understood as a functional interface for the time being.
In the process of programming, you will always encounter many functional interfaces. The following are some of the most important functional interfaces in JDK
Examples of interface parameter return types
Interface |
Parameters |
Return type |
Example |
##PredicateT | boolean | Is the value equal to "Hello"? |
Consumer | T | void | Output a value |
Function | T | R | Get a property of the object |
Supplier | None | T | Factory Method |
UnaryOperator | T | T | Logical NOT (!) |
BinaryOperator | (T, T) | T | Find the sum of 2 numbers ( ) |
2.4 类型推断
先看一段熟悉的集合代码
ArrayList<Java8Test> list = new ArrayList<>();
Copy after login
在ArrayList中申明了存储的元素的类型,于是在ArrayList<>()这里的类型可以缺省,编译器可以根据左侧(即上文)推断出来。
同理,在lambda表达式也是一样的。
BinaryOperator<Long> addLongs = (x, y) -> x + y;
Copy after login
在上面的表达 式中,我们注意到 (x, y)
这里是没有申明方法的参数类型的,却能执行数学运算 +
。
这里根据函数接口指定的泛型类为Long
,即可推断方法的参数为Long
,然后执行x + y
。
2.5 Lambda小结
Lambda表达式是一个匿名方法,简化了匿名内部类的写法,把模板语法屏蔽,突出业务语句,传达的更像一种行为。
Lambda表达式是有类型的,JDK内置了众多函数接口
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
Stream<String> StrStream = Stream.of("a", "b");
Copy after login
3.2.2 Stream.collect(Collector super T, A, R> collector)
使用收集器Collector
将StrStream
转化为熟悉的集合Collection
List<String> collect = StrStream.collect(Collectors.toList());
Copy after login
3.2.2 Stream.map(Function super T, ? extends R> mapper)
所谓map,从字面理解就是映射。这里指的是对象关系的映射,
比如从对象集合映射到属性结合:
List<String> names = Stream.of(new Student("zhangSan"), new Student("liSi"))
.map(student -> student.getName())
.collect(toList());
Copy after login
从小写字母映射到大写字母:
List<String> collected = Stream.of("a", "b", "hello")
.map(string -> string.toUpperCase())
.collect(toList());
Copy after login
将 字符串流 根据空格分割成 字符串数组流
Stream<String> stringStream = Stream.of("Hello Aron.");
Stream<String[]> stringArrayStream = stringStream.map(word -> word.split(" "));
Copy after login
3.2.3 Stream.filter(Predicate super T> predicate)
filter
顾名思义,过滤筛选。这里的参数函数接口是一个条件,筛选出满足条件的元素
// 筛选年龄大于19的学生
List<Student> stu = Stream.of(new Student("zhangSan", 19), new Student("liSi"), 20)
.filter(student -> student.getAge() > 19)
.collect(toList());
Copy after login
3.2.4 Stream.flatMap(Function super T, ? extends Stream extends R>> mapper)
flatMap
扁平化映射,即将数据元素为数组的Stream
转化为单个元素
Stream<String> stringStream = Stream.of("Hello Aron.");
// 返回值为数组
Stream<String[]> stringArrayStream = stringStream.map(word -> word.split(" "));
// flatMap扁平化映射后,元素都合并了
Stream<String> flatResult = stringArrayStream.flatMap(arr -> Arrays.stream(arr))
Copy after login
3.2.5 Stream.max(Comparator super T> comparator)
max
即最大,类似SQL
中的函数max()
,从数据中根据一定的条件筛选出最值
// 筛选年龄最大/小的学生
Stream<Student> studentStream = Stream.of(new Student("zhangSam", 19), new Student("liSi", 20));
Optional<Student> max = studentStream.max(Comparator.comparing(student -> student.getAge()));
// Optional<Student> max = studentStream.min(Comparator.comparing(student -> student.getAge()));
// 年龄最大/小的学生
Student student = max.get();
Copy after login
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);
Copy after login
上面代码,展开reduce()
操作
BinaryOperator<Integer> accumulator = (acc, element) -> acc + element;
int count = accumulator.apply( accumulator.apply(accumulator.apply(0, 1),2), 3);
Copy after login
3.2.8 综合操作
// 查找所有姓张的同学并按字典顺序排序,存储到list
List<Student> newList = studentList.Stream()
.filter(student -> student.getName().startsWith("张"))
.sorted(Comparator.comparing(student -> student.getName())
.collect(toList());
Copy after login
The above is the detailed content of Detailed explanation of Lambda and Stream in Java8 (with code). For more information, please follow other related articles on the PHP Chinese website!