常用函数式接口简单使用示例

一、概述

  • 在Java 8中引入了函数式编程的概念,并提供了一些新的函数式接口来支持函数式编程的需求。这些函数式接口可以简化代码、提高开发效率,并且可以应用于各种场景。

1、什么是函数式接口?

  • 函数式接口是指只包含一个抽象方法的接口。在Java中,函数式接口可以被赋予Lambda表达式或者方法引用,从而实现函数式编程的特性。Java 8引入了一些新的函数式接口,如Function、Consumer、Supplier和Predicate等。
  • java.util.function包下的都是

二、Function接口

  • Function接口表示一个接受一个参数并产生结果的函数。它定义了一个名为apply的抽象方法,用于执行具体的函数逻辑。Function接口常用于对输入进行转换、映射或者计算的场景。
  • 源码如下:
/**
* Represents a function that accepts one argument and produces a result.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #apply(Object)}.
*
* @param <T> the type of the input to the function
* @param <R> the type of the result of the function
*
* @since 1.8
*/
@FunctionalInterface
public interface Function<T, R> {

/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);

/**
* Returns a composed function that first applies the {@code before}
* function to its input, and then applies this function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of input to the {@code before} function, and to the
* composed function
* @param before the function to apply before this function is applied
* @return a composed function that first applies the {@code before}
* function and then applies this function
* @throws NullPointerException if before is null
*
* @see #andThen(Function)
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}

/**
* Returns a composed function that first applies this function to
* its input, and then applies the {@code after} function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of output of the {@code after} function, and of the
* composed function
* @param after the function to apply after this function is applied
* @return a composed function that first applies this function and then
* applies the {@code after} function
* @throws NullPointerException if after is null
*
* @see #compose(Function)
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}

/**
* Returns a function that always returns its input argument.
*
* @param <T> the type of the input and output objects to the function
* @return a function that always returns its input argument
*/
static <T> Function<T, T> identity() {
return t -> t;
}
}
  • 接收2个泛型:T(入参)和R(结果返回) ,默认需要实现的是R apply(T t) 方法。使用示例如下:
/**
* 脱敏策略
*/
@AllArgsConstructor
public enum SensitiveStrategy {

/**
* 身份证脱敏
*/
ID_CARD(s -> DesensitizedUtil.idCardNum(s, 3, 4)),

/**
* 手机号脱敏
*/
PHONE(DesensitizedUtil::mobilePhone),

/**
* 地址脱敏
*/
ADDRESS(s -> DesensitizedUtil.address(s, 8)),

/**
* 邮箱脱敏
*/
EMAIL(DesensitizedUtil::email),

/**
* 银行卡
*/
BANK_CARD(DesensitizedUtil::bankCard),
/**
* IP
*/
IP(DesensitizedUtil::ipv4),

/**
* 密码
*/
PASSWORD(DesensitizedUtil::password),

;

/**
* 可自行添加其他脱敏策略
*/
private final Function<String, String> desensitizer;

public Function<String, String> desensitizer() {
return desensitizer;
}
}
  • 还有其他2个默认方法:compose、andThen

    • compose: 返回一个组合函数,首先将入参应用到before函数,再将before函数结果应用到该函数中

      • Function<String, String> function = a -> a + " Jack!";
        Function<String, String> function1 = a -> a + " Bob!";
        String greet = function.compose(function1).apply("Hello");
        System.out.println(greet); // Hello Bob! Jack!
    • andThen: 返回一个组合函数,该函数结果应用到after函数中

      • Function<String, String> function = a -> a + " Jack!";
        Function<String, String> function1 = a -> a + " Bob!";
        String greet = function.andThen(function1).apply("Hello");
        System.out.println(greet); // Hello Jack! Bob!
  • 常用的还有:BiFunction<T,U,R> 接受两个参数并返回结果的函数

三、Consumer接口

  • Consumer接口表示一个接受一个参数但没有返回值的操作。它定义了一个名为accept的抽象方法,用于执行具体的操作逻辑。Consumer接口常用于对输入进行处理、消费或者打印的场景。
  • 示例:
public class ConsumerExample {
public static void main(String[] args) {
// 定义一个Consumer接口,打印输入的字符串
Consumer<String> printString = str -> System.out.println(str);

// 使用accept方法执行操作逻辑
printString.accept("hello world"); // 输出: hello world

}
}
  • BiConsumer<T,U> 提供两个自定义类型的输入参数,不返回执行结果

四、Supplier接口

  • Supplier接口表示一个不接受参数但返回结果的函数。它定义了一个名为get的抽象方法,用于获取具体的结果。Supplier接口常用于延迟计算或者提供默认值的场景。
// 示例1
Supplier<String> supplier = () -> "Hello Jack!";
System.out.println(supplier.get()); // Hello Jack!


// 示例2
public class SupplierExample {
public static void main(String[] args) {
String pwd1="a";
String pwd2="b";
checkError("2个字符串不相等",()->!pwd1.equals(pwd2));
}
private static void checkError(String errorMsg, Supplier<Boolean> supplier) {
if(supplier.get()){
throw new RuntimeException(errorMsg);
}
// todo
}
}

五、Predicate接口

  • Predicate接口表示一个接受一个参数并返回布尔值的函数。它定义了一个名为test的抽象方法,用于执行具体的判断逻辑。Predicate接口常用于过滤、筛选或者判断的场景
  • 简单示例如下:
public class PredicateExample {
public static void main(String[] args) {
// 定义一个Predicate接口,判断字符串是否以"Hello"开头
Predicate<String> startsWithHello = str -> str.startsWith("Hello");

// 使用test方法进行判断
boolean result1 = startsWithHello.test("Hello, World!");
boolean result2 = startsWithHello.test("Hi, there!");
System.out.println(result1); // 输出: true
System.out.println(result2); // 输出: false


// 定义一个Predicate接口,判断数字是否为偶数
Predicate<Integer> isEven = num -> num % 2 == 0;

// 使用test方法进行判断
boolean result1 = isEven.test(4);
boolean result2 = isEven.test(7);
System.out.println(result1); // 输出: true
System.out.println(result2);


// 组合判断
Predicate<Integer> isPositive = num -> num > 0;
// 组合两个Predicate
Predicate<Integer> isEvenAndPositive = isEven.and(isPositive);
boolean result1 = isEvenAndPositive.test(4); // 返回true,因为4既是偶数又是正数
boolean result2 = isEvenAndPositive.test(-3); // 返回false,因为-3不是正数

// 组合两个Predicate
Predicate<Integer> isEvenOrPositive = isEven.or(isPositive);
boolean result1 = isEvenOrPositive.test(4); // 返回true,因为4是偶数
boolean result2 = isEvenOrPositive.test(-3); // 返回true,因为-3是正数
boolean result3 = isEvenOrPositive.test(-2); // 返回false,因为-2既不是偶数或正数

// 取反操作
Predicate<Integer> isOdd = isEven.negate();
boolean result1 = isOdd.test(3); // 返回true,因为3是奇数
boolean result2 = isOdd.test(4); // 返回false,因为4是偶数


}
}
  • 还有其他的函数式接口和上面几个差不多可以参看:java.util.function
-------------本文结束 感谢您的阅读-------------