网站公告

本次更新:没啥更新的

“钱塘江上潮信起,今日方知我是我”

Skip to content

函数式接口 ​

字数: 0 字 时长: 0 分钟

1. 概述 ​

函数式接口是指:

只有一个抽象方法的接口。

JDK 中的函数式接口通常会使用 @FunctionalInterface 注解进行标识。

例如:

java
@FunctionalInterface
public interface Runnable {

    void run();
}

需要注意:

是否属于函数式接口,关键在于接口中是否只有一个抽象方法,而不是是否添加了 @FunctionalInterface 注解。

@FunctionalInterface 主要用于帮助编译器检查当前接口是否符合函数式接口的要求。

函数式接口也是 Lambda 表达式能够使用的基础。


2. 常见的函数式接口 ​

Java 中常见的函数式接口主要包括:

接口作用参数返回值
Consumer<T>消费数据有无
Function<T, R>转换数据有有
Predicate<T>判断条件有boolean
Supplier<T>提供数据无有

可以简单记成:

text
Consumer
   ↓
消费数据

Function
   ↓
转换数据

Predicate
   ↓
判断数据

Supplier
   ↓
提供数据

2.1 Consumer ​

Consumer<T> 是消费型接口。

它接收一个参数,对参数进行操作,但是没有返回值。

核心方法:

java
void accept(T t);

例如:

java
Consumer<String> consumer = str -> System.out.println(str);

consumer.accept("Hello");

image-20250324202651508


2.2 Function ​

Function<T, R> 是计算、转换型接口。

它接收一个参数,经过处理后返回另一个结果。

核心方法:

java
R apply(T t);

例如:

java
Function<String, Integer> function = str -> Integer.valueOf(str);

Integer result = function.apply("123");

可以理解为:

text
T
↓
处理 / 转换
↓
R

image-20250324202708994


2.3 Predicate ​

Predicate<T> 是判断型接口。

它接收一个参数,对参数进行条件判断,并返回 boolean。

核心方法:

java
boolean test(T t);

例如:

java
Predicate<Integer> predicate = num -> num > 18;

boolean result = predicate.test(20);

image-20250324202730721


2.4 Supplier ​

Supplier<T> 是生产型接口。

它不接收参数,只负责产生并返回一个结果。

核心方法:

java
T get();

例如:

java
Supplier<String> supplier = () -> "Hello";

String result = supplier.get();

可以理解为:

text
无参数
  ↓
创建 / 获取数据
  ↓
返回 T

image-20250324202750268


3. Predicate 常用默认方法 ​

Predicate 除了核心方法 test(),还提供了一些用于组合判断条件的默认方法:

text
and()
or()
negate()

3.1 and() ​

and() 用于连接两个判断条件,相当于逻辑运算中的:

java
&&

只有两个条件都满足时,最终结果才是 true。

例如:

打印年龄大于 17,并且姓名长度大于 1 的作者。

完整写法:

java
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 简化:

java
stream.filter(
        ((Predicate<Author>) author -> author.getAge() > 17)
                .and(author -> author.getName().length() > 1)
);

可以理解为:

text
年龄 > 17
    &&
姓名长度 > 1

3.2 and() 示例 ​

定义两个 IntPredicate:

java
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 简化:

java
printNum2(
        value -> value % 2 == 0,
        value -> value > 4
);

方法实现:

java
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);
        }
    }
}

这里的:

java
predicate.and(predicate2)

相当于:

text
value % 2 == 0
       &&
value > 4

3.3 or() ​

or() 用于连接两个判断条件,相当于逻辑运算中的:

java
||

只要其中一个条件满足,最终结果就是 true。

例如:

打印年龄大于 17,或者姓名长度小于 2 的作者。

java
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;
                        }
                    }
            )
    );
}

可以理解为:

text
年龄 > 17
    ||
姓名长度 < 2

3.4 negate() ​

negate() 用于对当前判断结果取反,相当于:

java
!

例如原条件:

java
author.getAge() > 17

使用 negate() 后相当于:

java
!(author.getAge() > 17)

也就是:

java
author.getAge() <= 17

例如:

打印年龄不大于 17 的作者。

java
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()));
}

可以理解为:

text
age > 17
   ↓
negate()
   ↓
age <= 17

4. 小结 ​

函数式接口的核心:

接口中只有一个抽象方法,就可以作为 Lambda 表达式的目标类型。

常见函数式接口:

text
Consumer<T>
    ↓
接收参数,不返回结果

Function<T, R>
    ↓
接收参数,返回转换后的结果

Predicate<T>
    ↓
接收参数,返回 boolean

Supplier<T>
    ↓
不接收参数,返回结果

Predicate 常用的条件组合方法:

text
and()
  ↓
&&

or()
  ↓
||

negate()
  ↓
!

Noctiflorous Garden · MIT License