Consumer 的使用(顾客)
Consumer 翻译过来的意思就是消费者,很容易理解,它就是一个只负责消费的接口。相当于你是一个餐馆的顾客,你只负责吃你点的食物。
在项目中一些不需要返回值,只负责消费的方法可以用过 Consumer 接口来实现。
示例代码
代码如下:
// 定义一个顾客(Consumer),用于消费食物 Consumer<String> customer = food -> System.out.println("吃掉了:" + food);// 厨师准备了一份美食 String food = "美味牛排";// 顾客吃掉厨师准备的食物 customer.accept(food);
Sa-Token源码中的使用
定义函数式接口:
/*** 函数式接口:对一个 [Method] 对象进行注解校验 (注解鉴权内部实现)** <p> 参数:Method句柄 </p>* <p> 返回:无 </p>** @author lingqi* @since 1.35.0*/ @FunctionalInterface public interface SaCheckMethodAnnotationFunction extends Consumer<Method> {}
具体实现:
/*** 对一个 [Method] 对象进行注解校验 (注解鉴权内部实现)*/ public SaCheckMethodAnnotationFunction checkMethodAnnotation = (method) -> {// 先校验 Method 所属 Class 上的注解 instance.checkElementAnnotation.accept(method.getDeclaringClass());// 再校验 Method 上的注解 instance.checkElementAnnotation.accept(method); };
源码
代码如下:
@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);};} }
从代码可以看出,Consumer提供了一个接收泛型的accept方法,返回值为void。
使用例子
数据的打印
代码如下:
//由 Consumer<String> printConsumer = (s) -> System.out.println(s); 简化 Consumer<String> printConsumer = System.out::println; printConsumer.accept("我是聪啊");
数据校验
代码如下:
Consumer<String> printConsumer = (s) -> {//判断字符串是否含有 congif (s.contains("cong")) {System.out.println("字符串含有 cong");} else {System.out.println("字符串不含有 cong");throw new RuntimeException("字符串不含 cong 啊");} }; printConsumer.accept("我是cong"); printConsumer.accept("我不是c1ong");
Supplier的使用(厨师)
Supplier 好比一名厨师,它只负责生产出美味的食物,从来不关心这些是否最终的流向哪位顾客食用。
示例代码
代码如下:
// 定义一个厨师(Supplier),用于供应食物 Supplier<String> chef = () -> "美味牛排";// 厨师提供食物 String food = chef.get(); System.out.println("厨师准备了:" + food);
Sa-Token源码中的使用
代码如下:
/*** OAuth-Server端:未登录时返回的View */ public Supplier<Object> notLoginView = () -> "当前会话在OAuth-Server认证中心尚未登录";
源码
代码如下:
@FunctionalInterface public interface Supplier<T> {T get(); }
代码十分简单,主要提供了一个返回泛型和接收泛型的 get 方法
使用例子
生成随机ID
代码如下:
//生成 uuid 由 Supplier<String> demoSupplier = () -> { return IdUtil.simpleUUID(); }; 简化 Supplier<String> demoSupplier = IdUtil::simpleUUID; demoSupplier.get();
生成对象
代码如下:
// 使用Supplier生成Person对象 Supplier<Person> personSupplier = () -> new Person("Alice");// 获取生成的Person对象 Person person = personSupplier.get(); System.out.println("Person's name: " + person.getName()); personSupplier.get();
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);
Sa-Token源码中的使用
代码如下:
/*** 函数式接口:创建 SaSession 的策略** <p> 参数:SessionId </p>* <p> 返回:SaSession对象 </p>** @author lingqi* @since 1.35.0*/ @FunctionalInterface public interface SaCreateSessionFunction extends Function<String, SaSession> {}
源码
代码如下:
@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;};} }
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);
函数组合
代码如下:
// 定义两个函数 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);
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("顾客选择了其他食物!"); }
源码
代码如下:
@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();} }
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
组合多个断言
代码如下:
// 定义两个断言 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