Java中的函数式编程通过Lambda表达式和Stream API实现了核心概念,包括高阶函数、不可变数据和函数组合。以下是详细的内容:
接口 | 方法 | 用途 | 示例 |
---|---|---|---|
Supplier | T get() | 无参生成值 | 工厂方法 |
Consumer | void accept(T t) | 消费一个参数 | 遍历集合元素 |
Function |
R apply(T t) | 转换输入为输出 | 字符串转整数 |
Predicate< | boolean test(T t) | 条件判断 | 过滤集合元素 |
BiFunction |
R apply(T t, U u) | 两个输入参数转换为输出 | 合并两个字符串 |
- Java提供了一系列函数式接口,如Consumer、Function、Supplier、Predicate等,作为Lambda表达式的类型。
- 这些接口通常只有一个抽象方法,Lambda表达式能够直接替换匿名类实现,简化代码。
->
用于定义匿名函数,可以传递作为参数或返回。() -> System.out.println("Hello")
和(x) -> x + 1
展示了无参和有参的情况。ImmutableList.of("a", "b")
创建不可变列表。Function f = x -> x.length();
。Function f = Function.identity().andThen(x -> x + "!");
将两个函数组合。Function<Integer, Integer> multiplyBy2 = x -> x * 2;
Function<Integer, Integer> add3 = x -> x + 3;
Function<Integer, Integer> combined = multiplyBy2.andThen(add3);
System.out.println(combined.apply(5)); // 输出 13 (5*2 +3)
List<String> list = Arrays.asList("apple", "banana", "cherry");
// 使用Lambda和Stream的forEach
list.stream()
.map(String::toUpperCase) // 转换为大写
.forEach(System.out::println); // 输出:APPLE BANANA CHERRY
int[] numbers = {1, 2, 3, 4, 5};
// 过滤 >2 的数并计算平均值
OptionalDouble avg = Arrays.stream(numbers)
.filter(n -> n > 2)
.average();
System.out.println("平均值: " + avg.orElse(0)); // 输出:平均值: 4.0
// 定义两个函数
Function<String, String> addExclamation = s -> s + "!";
Function<String, String> toUpperCase = String::toUpperCase;
// 组合函数:先执行addExclamation,再执行toUpperCase
Function<String, String> combined = addExclamation.andThen(toUpperCase);
String result = combined.apply("test");
System.out.println(result); // 输出:TEST!
// 创建不可变列表
ImmutableList<String> immutableList = ImmutableList.of("A", "B", "C");
try {
// 尝试修改列表(会抛出UnsupportedOperationException)
immutableList.add("D");
} catch (UnsupportedOperationException e) {
System.out.println("修改不可变列表时抛出异常!");
}
// 传统写法
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked");
}
});
// Lambda 简化
button.addActionListener(e -> System.out.println("Button clicked"));
List<Transaction> transactions = ...;
// 统计2023年大额交易总额(金额>1000)
double total = transactions.stream()
.filter(t -> t.getYear() == 2023)
.filter(t -> t.getAmount() > 1000)
.mapToDouble(Transaction::getAmount)
.sum();
Map<String, Double> avgScoreBySubject = students.stream()
.collect(Collectors.groupingBy(
Student::getSubject,
Collectors.averagingDouble(Student::getScore)
));
// 输出: {Math=85.5, Physics=78.0}
List<String> fileContents = files.stream()
.map(file -> {
try {
return Files.readString(file.toPath());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
})
.collect(Collectors.toList());
特性 | 命令式编程 | 函数式编程 |
---|---|---|
代码风格 | 如何做(How) | 做什么(What) |
状态管理 | 可变状态 | 不可变数据 |
并行处理 | 需显式同步 | 隐式线程安全 |
代码重用 | 类继承/组合 | 函数组合 |
典型结构 | 循环/条件分支 | 流水线操作链 |
最终建议:
通过合理运用函数式编程特性,可以显著提升Java代码的简洁性和可维护性,特别是在处理现代大数据量和高并发场景时表现出色。
Java通过函数式接口、Lambda表达式和Stream API支持函数式编程,提升了代码简洁性和效率。函数式编程强调不可变数据和高阶函数,适用于数据处理、并发编程等场景。合理应用这些特性,可以编写更高效、易维护的代码。