- Lambda表达式
- 函数式接口
- 链式编程
- Stream流式计算
1、Lambda表达式
-
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
-
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
-
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
-
Lambda表达式的标准格式由三部分组成
一些参数 一个箭头 -> 一段代码 格式:(参数列表)-> {重写的代码}
lambda表达式的重要特征:
-
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
-
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
-
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
-
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
// 1. 不需要参数,返回值为 5 () -> 5 // 2. 接收一个参数(数字类型),返回其2倍的值 x -> 2 * x // 3. 接受2个参数(数字),并返回他们的差值 (x, y) -> x – y // 4. 接收2个int型整数,返回他们的和 (int x, int y) -> x + y // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void) (String s) -> System.out.print(s)
2、函数式接口
面向对象编程思想:需要做一件事,找一个能完成这件事的对象,通过调用对象来完成这件事,函数式编程体现就是Lambda表达式。
函数式编程思想:只要事情的接口,至于谁去做,怎么做都不重要,重视结果,不在乎过程。
函数式接口:有且仅有一个抽象方法的接口,例如Runable
四种常用的函数式接口:
-
Supplier 你要作为一个供应者,自己生产数据
-
Consumer 你要作为一个消费者,利用已经准备数据
-
Function 输入一个或者两个不同或者相同的值转为另一个值
-
Predicate 输入一个或者两个不同或者相同的值总是输出boolean
3、链式编程
链式编程的原理就是返回一个this对象,就是返回本身,达到链式效果。
链式的写法:
StringBuffer builder = new StringBuffer();
builder.append("bobo").append("like").append("to").append("learn").append("Java");
4、Stream流式计算
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
Stream流常用的方法分为两类:
- 延迟方法:返回类型仍是Stream接口自身类型的方法,因此支持链式编程,此类方法有 filter,limit,skip等。
- 终结方法:返回类型不再是Stream接口自身类型的方法,因此不在支持链式编程,此类方法有count和foreach。
常用方法:
逐一处理:forEach ,会将每一个流元素交给该函数进行处理
public static void main(String[] args) {
Stream<String> stream = Stream.of("张无忌", "张三丰", "周芷若");
stream.forEach(name‐> System.out.println(name));
}
过滤:filter,可以通过 filter 方法将一个流转换成另一个子集流
public static void main(String[] args) {
Stream<String> original = Stream.of("张无忌", "张三丰", "周芷若");
Stream<String> result = original.filter(s ‐> s.startsWith("张"));
}
映射:map,如果需要将流中的元素映射到另一个流中
public static void main(String[] args) {
Stream<String> original = Stream.of("10", "12", "18");
Stream<Integer> result = original.map(str‐>Integer.parseInt(str));
}
统计个数:count,数一数其中的元素个数
public static void main(String[] args) {
Stream<String> original = Stream.of("张无忌", "张三丰", "周芷若");
Stream<String> result = original.filter(s ‐> s.startsWith("张"));
System.out.println(result.count()); // 2
}
取用前几个:limit,可以对流进行截取,只取用前n个
public static void main(String[] args) {
Stream<String> original = Stream.of("张无忌", "张三丰", "周芷若");
Stream<String> result = original.limit(2);
System.out.println(result.count()); // 2
}
跳过前几个:skip,如果希望跳过前几个元素
public static void main(String[] args) {
Stream<String> original = Stream.of("张无忌", "张三丰", "周芷若");
Stream<String> result = original.skip(2);
System.out.println(result.count()); // 1
}
组合:concat,如果有两个流,希望合并成为一个流
public static void main(String[] args) {
Stream<String> streamA = Stream.of("张无忌");
Stream<String> streamB = Stream.of("张翠山");
Stream<String> result = Stream.concat(streamA, streamB);
5、四类操作的综合应用
filter,forEach方法的参数都是函数式接口,同时Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)
public class StreamFilter {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
list.stream().filter(s -> s.startsWith("张")) .filter(s -> s.length() == 3) .forEach(System.out::println); }
}