Java案例怎么自定义函数接口?

wen java案例 14

本文目录导读:

Java案例怎么自定义函数接口?

  1. 自定义函数接口的核心规则
  2. 基本示例
  3. 带多个参数的自定义函数接口
  4. 泛型自定义函数接口
  5. 包含 default 方法的函数接口
  6. 实际项目中的完整示例
  7. 与 Java 内置函数式接口的对比
  8. 一个带有异常处理的函数接口

在Java中,自定义函数接口主要有两种方式:使用 @FunctionalInterface 注解显式定义,或者直接使用已有的函数式接口(如 FunctionConsumer 等),但如果你需要完全自定义,可以按照以下步骤。


自定义函数接口的核心规则

  • 接口中只能有一个抽象方法(SAM – Single Abstract Method)。
  • 可以使用 @FunctionalInterface 注解(可选,但推荐,编译器会检查是否满足条件)。
  • 可以包含 default 方法、static 方法、Object 类的方法。

基本示例

示例1:一个简单的转换接口

@FunctionalInterface
interface StringConverter {
    String convert(String input);
}

使用方式(Lambda 表达式):

StringConverter toUpperCase = str -> str.toUpperCase();
System.out.println(toUpperCase.convert("hello"));  // 输出 HELLO

带多个参数的自定义函数接口

@FunctionalInterface
interface MathOperation {
    int operate(int a, int b);
}

使用:

MathOperation add = (a, b) -> a + b;
System.out.println(add.operate(3, 4));  // 7

泛型自定义函数接口

@FunctionalInterface
interface Comparator<T> {
    int compare(T a, T b);  // 抽象方法
}

使用(Lambda + 泛型):

Comparator<String> lengthComparator = (s1, s2) -> s1.length() - s2.length();
System.out.println(lengthComparator.compare("hi", "hello"));  // -3

注意:这里的 Comparator 是自定义的,与 java.util.Comparator 无关。


包含 default 方法的函数接口

@FunctionalInterface
interface Greeting {
    void sayHello(String name);  // 唯一抽象方法
    default void sayGoodbye(String name) {
        System.out.println("Goodbye, " + name);
    }
}

使用:

Greeting greet = name -> System.out.println("Hello, " + name);
greet.sayHello("Alice");       // Hello, Alice
greet.sayGoodbye("Alice");     // Goodbye, Alice

实际项目中的完整示例

假设你需要一个处理用户对象的函数接口:

@FunctionalInterface
interface UserProcessor {
    void process(User user);
}
class User {
    private String name;
    private int age;
    // 构造方法、getter/setter 省略
}

使用:

UserProcessor printName = user -> System.out.println(user.getName());
UserProcessor checkAdult = user -> {
    if (user.getAge() >= 18) {
        System.out.println(user.getName() + " is adult");
    }
};

也可以结合方法引用:

UserProcessor printUserInfo = System.out::println;  // 需要 User 有 toString

与 Java 内置函数式接口的对比

场景 内置接口 完全自定义的时机
参数 → 返回值 Function<T,R> 需要更有意义的命名,如 UrlResolver
无参 → 返回值 Supplier<T> 业务语义不匹配时
参数 → void Consumer<T> 需要语义化的名称
参数 → boolean Predicate<T> PositiveNumberChecker

建议:优先使用内置函数接口(java.util.function 包下),除非你需要更强的语义表达特殊的参数/返回类型组合


一个带有异常处理的函数接口

默认的函数式接口不支持受检异常(checked exception),你可以自定义一个:

@FunctionalInterface
interface ThrowingFunction<T, R, E extends Exception> {
    R apply(T t) throws E;
}

使用:

ThrowingFunction<String, Integer, IOException> parser = str -> {
    if (str.isEmpty()) throw new IOException("empty string");
    return Integer.parseInt(str);
};

调用时需要处理异常:

try {
    int result = parser.apply("123");
} catch (IOException e) {
    e.printStackTrace();
}

步骤 说明
1 定义接口,添加 @FunctionalInterface 注解
2 仅保留一个抽象方法
3 可添加 default/static 方法
4 支持泛型实现复用
5 用 Lambda 或方法引用实例化

实战建议:除非你需要表达特别明确的业务语义,否则优先使用 java.util.function 包中已有的接口,如果确实需要自定义,务必加上 @FunctionalInterface 注解让编译器帮你检查。

抱歉,评论功能暂时关闭!