Java 函数式接口是一种特殊的接口,它只包含一个抽象方法(Single Abstract Method, SAM),但可以包含多个默认方法或静态方法。函数式接口是 Java 8 引入 Lambda 表达式的基础,通过函数式接口可以将行为作为参数传递,实现更简洁、灵活的代码。
java.util.function
包中提供了一系列通用的函数式接口,如 Predicate
、Function
、Consumer
等。Java 8 提供了四大核心函数式接口,覆盖了常见的函数式编程场景:
Predicate
接收一个参数,返回布尔值,用于判断条件。
@FunctionalInterface
public interface Predicate {
boolean test(T t);
}
// 使用示例
Predicate isEven = num -> num % 2 == 0;
System.out.println(isEven.test(4)); // 输出: true
Function
接收一个参数,返回另一个类型的结果,用于类型转换。
@FunctionalInterface
public interface Function {
R apply(T t);
}
// 使用示例
Function strLength = s -> s.length();
System.out.println(strLength.apply("hello")); // 输出: 5
Consumer
接收一个参数,不返回结果,用于消费数据。
@FunctionalInterface
public interface Consumer {
void accept(T t);
}
// 使用示例
Consumer printer = s -> System.out.println(s);
printer.accept("Hello, World!"); // 输出: Hello, World!
Supplier
不接收参数,返回一个结果,用于提供数据。
@FunctionalInterface
public interface Supplier {
T get();
}
// 使用示例
Supplier randomSupplier = () -> Math.random();
System.out.println(randomSupplier.get()); // 输出随机数
可以通过 @FunctionalInterface
注解定义自己的函数式接口:
@FunctionalInterface
public interface Calculator {
int calculate(int a, int b); // 唯一的抽象方法
// 默认方法(非抽象)
default void printResult(int result) {
System.out.println("计算结果: " + result);
}
}
// 使用 Lambda 表达式实现
Calculator adder = (a, b) -> a + b;
Calculator subtractor = (a, b) -> a - b;
System.out.println(adder.calculate(5, 3)); // 输出: 8
adder.printResult(10); // 输出: 计算结果: 10
方法引用是 Lambda 表达式的一种简化形式,用于直接引用已存在的方法。
// Lambda 表达式
Function parseInt = s -> Integer.parseInt(s);
// 方法引用
Function parseIntRef = Integer::parseInt;
// Lambda 表达式
Consumer printer = s -> System.out.println(s);
// 方法引用
Consumer printerRef = System.out::println;
// Lambda 表达式
Supplier> listSupplier = () -> new ArrayList<>();
// 方法引用
Supplier> listSupplierRef = ArrayList::new;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FilterExample {
public static void main(String[] args) {
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
// 过滤偶数
List evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0) // 使用 Predicate
.collect(Collectors.toList());
System.out.println(evenNumbers); // 输出: [2, 4, 6]
}
}
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapExample {
public static void main(String[] args) {
List words = Arrays.asList("hello", "world");
// 转换为大写
List upperCaseWords = words.stream()
.map(String::toUpperCase) // 使用 Function
.collect(Collectors.toList());
System.out.println(upperCaseWords); // 输出: [HELLO, WORLD]
}
}
@FunctionalInterface
public interface ClickListener {
void onClick(String event);
}
public class Button {
private ClickListener listener;
public void setOnClickListener(ClickListener listener) {
this.listener = listener;
}
public void simulateClick() {
if (listener != null) {
listener.onClick("Button clicked");
}
}
}
// 使用 Lambda 表达式处理事件
Button button = new Button();
button.setOnClickListener(event -> System.out.println("处理事件: " + event));
button.simulateClick(); // 输出: 处理事件: Button clicked
题目:
答案:
函数式接口是 Java 函数式编程的核心,它结合 Lambda 表达式和方法引用,使代码更简洁、更具表现力。关键要点包括:
Predicate
、Function
、Consumer
和 Supplier
覆盖了常见场景。在实际开发中,函数式接口常用于回调、事件处理、集合操作等场景,能够有效减少样板代码,提升开发效率。但需注意避免过度使用复杂的 Lambda 表达式,保持代码的可维护性。