# 函数式接口的使用

作者:聪ζ (opens new window)编程导航星球 (opens new window) 编号 12852

介绍 Consumer、Supplier、Predicate与Function 接口的使用

# Consumer 的使用(顾客)

Consumer 翻译过来的意思就是消费者,很容易理解,它就是一个只负责消费的接口。相当于你是一个餐馆的顾客,你只负责吃你点的食物。

在项目中一些不需要返回值,只负责消费的方法可以用过 Consumer 接口来实现。

# 示例代码

代码如下:

// 定义一个顾客(Consumer),用于消费食物
Consumer<String> customer = food -> System.out.println("吃掉了:" + food);

// 厨师准备了一份美食
String food = "美味牛排";

// 顾客吃掉厨师准备的食物
customer.accept(food);
1
2
3
4
5
6
7
8

# Sa-Token 源码中的使用

定义函数式接口:

/**
 * 函数式接口:对一个 [Method] 对象进行注解校验 (注解鉴权内部实现)
 *
 * <p>  参数:Method句柄  </p>
 * <p>  返回:无  </p>
 *
 * @author click33
 * @since 1.35.0
 */
@FunctionalInterface
public interface SaCheckMethodAnnotationFunction extends Consumer<Method> {

}
1
2
3
4
5
6
7
8
9
10
11
12
13

具体实现:

/**
 * 对一个 [Method] 对象进行注解校验 (注解鉴权内部实现)
 */
public SaCheckMethodAnnotationFunction checkMethodAnnotation = (method) -> {

    // 先校验 Method 所属 Class 上的注解
    instance.checkElementAnnotation.accept(method.getDeclaringClass());

    // 再校验 Method 上的注解
    instance.checkElementAnnotation.accept(method);
};
1
2
3
4
5
6
7
8
9
10
11

# 源码

代码如下:

@FunctionalInterface
public interface Consumer<T> {
    void accept(T var1);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (t) -> {
            this.accept(t);
            after.accept(t);
        };
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

从代码可以看出,Consumer提供了一个接收泛型的 accept方法,返回值为 void。

# 使用例子

# 数据的打印

代码如下:

//由 Consumer<String> printConsumer = (s) -> System.out.println(s); 简化
Consumer<String> printConsumer = System.out::println;
printConsumer.accept("我是聪啊");
1
2
3

# 数据校验

代码如下:

Consumer<String> printConsumer = (s) -> {
    //判断字符串是否含有 cong
    if (s.contains("cong")) {
        System.out.println("字符串含有 cong");
    } else {
        System.out.println("字符串不含有 cong");
        throw new RuntimeException("字符串不含 cong 啊");
    }
};
printConsumer.accept("我是cong");
printConsumer.accept("我不是c1ong");
1
2
3
4
5
6
7
8
9
10
11

# Supplier 的使用(厨师)

Supplier 好比一名厨师,它只负责生产出美味的食物,从来不关心这些是否最终的流向哪位顾客食用。

# 示例代码

代码如下:

// 定义一个厨师(Supplier),用于供应食物
Supplier<String> chef = () -> "美味牛排";

// 厨师提供食物
String food = chef.get();
System.out.println("厨师准备了:" + food);
1
2
3
4
5
6

# Sa-Token 源码中的使用

代码如下:

/**
 * OAuth-Server端:未登录时返回的View 
 */
public Supplier<Object> notLoginView = () -> "当前会话在OAuth-Server认证中心尚未登录";
1
2
3
4

# 源码

代码如下:

@FunctionalInterface
public interface Supplier<T> {
    T get();
}
1
2
3
4

代码十分简单,主要提供了一个返回泛型和接收泛型的 get 方法

# 使用例子

# 生成随机 ID

代码如下:

//生成 uuid 由 Supplier<String> demoSupplier = () -> { return IdUtil.simpleUUID(); }; 简化
Supplier<String> demoSupplier = IdUtil::simpleUUID;
demoSupplier.get();
1
2
3

# 生成对象

代码如下:

// 使用Supplier生成Person对象
Supplier<Person> personSupplier = () -> new Person("Alice");

// 获取生成的Person对象
Person person = personSupplier.get();
System.out.println("Person's name: " + person.getName());
personSupplier.get();
1
2
3
4
5
6
7

# Function 的使用(服务员)

在餐厅里,服务员(Function)负责将厨师提供的食物送到顾客手中,服务员根据顾客的需求将食物进行加工或处理(例如加调料、切成小块等)。

在 Java 中,Function<T, R> 表示一个函数,它接收一个输入(食物)并返回一个输出(处理后的食物)。

# 示例代码

代码如下:

// 定义一个服务员(Function),用于加工食物
Function<String, String> waiter = food -> "加工后的" + food;

// 厨师提供食物
Supplier<String> chef = () -> "美味牛排";
String food = chef.get();

// 服务员加工食物后送到顾客手中
String processedFood = waiter.apply(food);
System.out.println("服务员送来了:" + processedFood);
1
2
3
4
5
6
7
8
9
10

# Sa-Token 源码中的使用

代码如下:

/**
 * 函数式接口:创建 SaSession 的策略
 *
 * <p>  参数:SessionId  </p>
 * <p>  返回:SaSession对象  </p>
 *
 * @author click33
 * @since 1.35.0
 */
@FunctionalInterface
public interface SaCreateSessionFunction extends Function<String, SaSession> {

}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 源码

代码如下:

@FunctionalInterface
public interface Function<T, R> {
    R apply(T var1);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (v) -> {
            return this.apply(before.apply(v));
        };
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (t) -> {
            return after.apply(this.apply(t));
        };
    }

    static <T> Function<T, T> identity() {
        return (t) -> {
            return t;
        };
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

Function<T, R> 是一个函数型接口,代表接受一个输入参数(类型为T),并返回一个结果(类型为R)的操作。它定义了一个名为 apply 的抽象方法,用于执行转换或计算。

# 使用例子

# 字符串转换为整数

代码如下:

// 定义一个函数,将字符串转换为整数
Function<String, Integer> stringToInt = str -> Integer.parseInt(str);

// 使用函数将字符串转换为整数
String numberStr = "123";
Integer number = stringToInt.apply(numberStr);

System.out.println("Converted integer: " + number);
1
2
3
4
5
6
7
8

# 函数组合

代码如下:

// 定义两个函数
Function<String, Integer> strToInt = str -> Integer.parseInt(str);
Function<Integer, String> intToStr = num -> "Number: " + num;

// 将两个函数进行组合
Function<String, String> composedFunction = strToInt.andThen(intToStr);

// 使用组合函数进行转换
String numberStr = "123";
String result = composedFunction.apply(numberStr);

System.out.println("Result: " + result);
1
2
3
4
5
6
7
8
9
10
11
12

# Predicate 的使用(菜单选择标准)

在餐厅里,菜单上的每道菜(Predicate)都有自己的特点或标准,顾客可以根据菜单上的描述(Predicate)来选择自己喜欢的食物。

在 Java 中,Predicate 表示一个断言,用于判断对象是否符合特定的条件。

# 示例代码

代码如下:

// 定义一个菜单选择标准(Predicate)
Predicate<String> isSteak = food -> food.equals("美味牛排");

// 厨师提供食物
Supplier<String> chef = () -> "美味牛排";
String food = chef.get();

// 判断食物是否符合菜单选择标准
if (isSteak.test(food)) {
    System.out.println("顾客点了牛排!");
} else {
    System.out.println("顾客选择了其他食物!");
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 源码

代码如下:

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T var1);

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> {
            return this.test(t) && other.test(t);
        };
    }

    default Predicate<T> negate() {
        return (t) -> {
            return !this.test(t);
        };
    }

    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> {
            return this.test(t) || other.test(t);
        };
    }

    static <T> Predicate<T> isEqual(Object targetRef) {
        return null == targetRef ? Objects::isNull : (object) -> {
            return targetRef.equals(object);
        };
    }

    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return target.negate();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

Predicate 是一个断言型接口,代表一个断言(输入一个参数,返回一个布尔值的判断)。它定义了一个名为 test 的抽象方法,用于执行条件判断。

# 使用示例

# 判断是否是偶数

代码如下:

// 使用 Predicate 接口判断是否是偶数
Predicate<Integer> isEven = num -> num % 2 == 0;
System.out.println("Is 4 even? " + isEven.test(4)); // true
System.out.println("Is 7 even? " + isEven.test(7)); // false
1
2
3
4

# 组合多个断言

代码如下:

 // 定义两个断言
Predicate<Integer> isEven = num -> num % 2 == 0;
Predicate<Integer> isPositive = num -> num > 0;

// 使用逻辑操作符组合断言
Predicate<Integer> isEvenAndPositive = isEven.and(isPositive);

// 测试组合断言
System.out.println("Is 6 even and positive? " + isEvenAndPositive.test(6)); // true
System.out.println("Is -3 even and positive? " + isEvenAndPositive.test(-3)); // false
System.out.println("Is 9 even and positive? " + isEvenAndPositive.test(9)); // false
1
2
3
4
5
6
7
8
9
10
11
最近更新: 4/19/2024, 9:56:50 AM
编程导航   |