14人参与 • 2026-04-30 • Java
在 java 8 引入的函数式编程范式中,function<t, r> 接口是核心组件之一,它代表接受一个参数并产生结果的函数。而 andthen 方法则提供了强大的函数组合能力,允许将多个函数串联成一个复杂的处理流程。
本文将从基础概念入手,逐步深入探讨 function 接口及其组合机制的原理与应用。
function<t, r> 是一个函数式接口,位于 java.util.function 包中,其核心定义如下:
@functionalinterface
public interface function<t, r> {
r apply(t t);
default <v> function<t, v> andthen(function<? super r, ? extends v> after) {
objects.requirenonnull(after);
return (t t) -> after.apply(apply(t));
}
default <v> function<v, r> compose(function<? super v, ? extends t> before) {
objects.requirenonnull(before);
return (v v) -> apply(before.apply(v));
}
static <t> function<t, t> identity() {
return t -> t;
}
}
类型参数:
t:输入参数的类型r:返回结果的类型核心方法:
apply(t t):执行函数逻辑,返回结果andthen(function):函数组合,先执行当前函数,再执行后续函数compose(function):函数组合,先执行前置函数,再执行当前函数identity():返回一个始终返回输入参数的函数// 将字符串转换为大写
function<string, string> touppercase = s -> s.touppercase();
string result = touppercase.apply("hello"); // 输出:hello
// 将字符串转换为其长度
function<string, integer> lengthfunction = s -> s.length();
integer length = lengthfunction.apply("hello"); // 输出:5
class emailvalidator implements function<string, boolean> {
@override
public boolean apply(string email) {
return email != null && email.contains("@");
}
}
// 使用自定义函数
function<string, boolean> validator = new emailvalidator();
boolean isvalid = validator.apply("test@example.com"); // 输出:true
andthen 方法允许将多个 function 组合成一个新的 function,执行顺序为:先执行当前 function,再执行传入的 function。
// 定义两个简单函数 function<integer, integer> multiplybytwo = num -> num * 2; function<integer, integer> addten = num -> num + 10; // 组合函数:先乘以2,再加10 function<integer, integer> combined = multiplybytwo.andthen(addten); int result = combined.apply(5); // 执行流程:5 * 2 + 10 = 20
// 定义三个函数
function<string, string> removewhitespace = s -> s.replaceall("\\s", "");
function<string, string> touppercase = s -> s.touppercase();
function<string, string> addprefix = s -> "[prefix] " + s;
// 组合多个函数
function<string, string> pipeline = removewhitespace
.andthen(touppercase)
.andthen(addprefix);
string result = pipeline.apply(" hello world ");
// 执行流程:" hello world " -> "helloworld" -> "helloworld" -> "[prefix] helloworld"
compose 方法同样用于函数组合,但执行顺序与 andthen 相反:先执行传入的 function,再执行当前 function。
function<integer, integer> multiplybytwo = num -> num * 2; function<integer, integer> addten = num -> num + 10; // 使用 andthen:先乘2,再加10 function<integer, integer> combined1 = multiplybytwo.andthen(addten); int result1 = combined1.apply(5); // 计算:(5 * 2) + 10 = 20 // 使用 compose:先加10,再乘2 function<integer, integer> combined2 = multiplybytwo.compose(addten); int result2 = combined2.apply(5); // 计算:(5 + 10) * 2 = 30
执行顺序总结:
f.andthen(g) 等价于 g(f(x))f.compose(g) 等价于 f(g(x))function 接口在 stream api 中被广泛用于映射操作:
import java.util.arrays;
import java.util.list;
import java.util.function.function;
import java.util.stream.collectors;
public class streammapexample {
public static void main(string[] args) {
list<string> words = arrays.aslist("apple", "banana", "cherry");
// 定义函数:转换为大写并截取前3个字符
function<string, string> processword = s -> s.touppercase().substring(0, 3);
// 在 stream 中使用函数
list<string> result = words.stream()
.map(processword)
.collect(collectors.tolist());
system.out.println(result); // 输出:[app, ban, che]
}
}
import java.util.arraylist;
import java.util.list;
import java.util.function.function;
public class dynamicfunctionchain {
public static void main(string[] args) {
// 动态构建函数链
list<function<string, string>> functions = new arraylist<>();
functions.add(s -> s.replace(" ", "_"));
functions.add(string::touppercase);
functions.add(s -> "[" + s + "]");
// 组合所有函数
function<string, string> pipeline = functions.stream()
.reduce(function.identity(), function::andthen);
string result = pipeline.apply("hello world");
// 输出:[hello_world]
}
}
import java.util.function.function;
public class functionfactory {
// 创建一个将字符串重复指定次数的函数
public static function<string, string> repeatfunction(int times) {
return s -> {
stringbuilder sb = new stringbuilder();
for (int i = 0; i < times; i++) {
sb.append(s);
}
return sb.tostring();
};
}
public static void main(string[] args) {
function<string, string> triple = repeatfunction(3);
string result = triple.apply("abc"); // 输出:abcabcabc
}
}
避免函数链过长:
处理异常:
apply 方法不声明检查异常,若需要处理异常,可考虑使用自定义函数式接口使用泛型上限和下限:
? super t 和 ? extends r 确保类型安全利用 identity () 方法:
function.identity() 可作为初始值,避免空指针问题java 的 function 接口与 andthen 组合机制为函数式编程提供了强大的工具,通过合理运用可以:
在实际开发中,建议将常用的函数定义为静态常量或通过工厂方法生成,并通过组合操作构建更高级的业务逻辑,从而使代码更加简洁、灵活和可维护。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论