函数式接口
字数: 0 字 时长: 0 分钟
1. 概述
函数式接口是指:
只有一个抽象方法的接口。
JDK 中的函数式接口通常会使用 @FunctionalInterface 注解进行标识。
例如:
@FunctionalInterface
public interface Runnable {
void run();
}需要注意:
是否属于函数式接口,关键在于接口中是否只有一个抽象方法,而不是是否添加了
@FunctionalInterface注解。
@FunctionalInterface 主要用于帮助编译器检查当前接口是否符合函数式接口的要求。
函数式接口也是 Lambda 表达式能够使用的基础。
2. 常见的函数式接口
Java 中常见的函数式接口主要包括:
| 接口 | 作用 | 参数 | 返回值 |
|---|---|---|---|
Consumer<T> | 消费数据 | 有 | 无 |
Function<T, R> | 转换数据 | 有 | 有 |
Predicate<T> | 判断条件 | 有 | boolean |
Supplier<T> | 提供数据 | 无 | 有 |
可以简单记成:
Consumer
↓
消费数据
Function
↓
转换数据
Predicate
↓
判断数据
Supplier
↓
提供数据2.1 Consumer
Consumer<T> 是消费型接口。
它接收一个参数,对参数进行操作,但是没有返回值。
核心方法:
void accept(T t);例如:
Consumer<String> consumer = str -> System.out.println(str);
consumer.accept("Hello");
2.2 Function
Function<T, R> 是计算、转换型接口。
它接收一个参数,经过处理后返回另一个结果。
核心方法:
R apply(T t);例如:
Function<String, Integer> function = str -> Integer.valueOf(str);
Integer result = function.apply("123");可以理解为:
T
↓
处理 / 转换
↓
R
2.3 Predicate
Predicate<T> 是判断型接口。
它接收一个参数,对参数进行条件判断,并返回 boolean。
核心方法:
boolean test(T t);例如:
Predicate<Integer> predicate = num -> num > 18;
boolean result = predicate.test(20);
2.4 Supplier
Supplier<T> 是生产型接口。
它不接收参数,只负责产生并返回一个结果。
核心方法:
T get();例如:
Supplier<String> supplier = () -> "Hello";
String result = supplier.get();可以理解为:
无参数
↓
创建 / 获取数据
↓
返回 T
3. Predicate 常用默认方法
Predicate 除了核心方法 test(),还提供了一些用于组合判断条件的默认方法:
and()
or()
negate()3.1 and()
and() 用于连接两个判断条件,相当于逻辑运算中的:
&&只有两个条件都满足时,最终结果才是 true。
例如:
打印年龄大于 17,并且姓名长度大于 1 的作者。
完整写法:
List<Author> authors = getAuthors();
Stream<Author> stream = authors.stream();
stream.filter(
new Predicate<Author>() {
@Override
public boolean test(Author author) {
return author.getAge() > 17;
}
}.and(
new Predicate<Author>() {
@Override
public boolean test(Author author) {
return author.getName().length() > 1;
}
}
)
);Lambda 简化:
stream.filter(
((Predicate<Author>) author -> author.getAge() > 17)
.and(author -> author.getName().length() > 1)
);可以理解为:
年龄 > 17
&&
姓名长度 > 13.2 and() 示例
定义两个 IntPredicate:
printNum2(
new IntPredicate() {
@Override
public boolean test(int value) {
return value % 2 == 0;
}
},
new IntPredicate() {
@Override
public boolean test(int value) {
return value > 4;
}
}
);Lambda 简化:
printNum2(
value -> value % 2 == 0,
value -> value > 4
);方法实现:
public static void printNum2(
IntPredicate predicate,
IntPredicate predicate2) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
if (predicate.and(predicate2).test(i)) {
System.out.println(i);
}
}
}这里的:
predicate.and(predicate2)相当于:
value % 2 == 0
&&
value > 43.3 or()
or() 用于连接两个判断条件,相当于逻辑运算中的:
||只要其中一个条件满足,最终结果就是 true。
例如:
打印年龄大于 17,或者姓名长度小于 2 的作者。
public static void main(String[] args) {
List<Author> authors = getAuthors();
Stream<Author> stream = authors.stream();
stream.filter(
new Predicate<Author>() {
@Override
public boolean test(Author author) {
return author.getAge() > 17;
}
}.or(
new Predicate<Author>() {
@Override
public boolean test(Author author) {
return author.getName().length() < 2;
}
}
)
);
}可以理解为:
年龄 > 17
||
姓名长度 < 23.4 negate()
negate() 用于对当前判断结果取反,相当于:
!例如原条件:
author.getAge() > 17使用 negate() 后相当于:
!(author.getAge() > 17)也就是:
author.getAge() <= 17例如:
打印年龄不大于 17 的作者。
public static void main(String[] args) {
List<Author> authors = getAuthors();
Stream<Author> stream = authors.stream();
stream.filter(
new Predicate<Author>() {
@Override
public boolean test(Author author) {
return author.getAge() > 17;
}
}.negate()
).forEach(author -> System.out.println(author.getAge()));
}可以理解为:
age > 17
↓
negate()
↓
age <= 174. 小结
函数式接口的核心:
接口中只有一个抽象方法,就可以作为 Lambda 表达式的目标类型。
常见函数式接口:
Consumer<T>
↓
接收参数,不返回结果
Function<T, R>
↓
接收参数,返回转换后的结果
Predicate<T>
↓
接收参数,返回 boolean
Supplier<T>
↓
不接收参数,返回结果Predicate 常用的条件组合方法:
and()
↓
&&
or()
↓
||
negate()
↓
!