为啥我不能用相同的参数类型组合两个不同的函数?
Posted
技术标签:
【中文标题】为啥我不能用相同的参数类型组合两个不同的函数?【英文标题】:Why can't I compose two different functions with identical parameter types?为什么我不能用相同的参数类型组合两个不同的函数? 【发布时间】:2022-01-22 05:29:43 【问题描述】:我有以下代码:
Function<String,Integer> f1=s->Integer.valueOf(s)+1;
Function<String,Integer> f2=s->Integer.valueOf(s)*2;
Function<String,Integer> f3=f1.compose(f2);
这是我得到的错误:
method compose in interface Function<T,R> cannot be applied to given types;
这段代码有什么问题?
然后我查看了文档中的compose()
:
default <V> Function<V, R> compose(Function<? super V, ? extends T> before)
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
我无法完全理解它。谁能给我解释一下可以组合的函数的参数之间的关系?
【问题讨论】:
【参考方案1】:组合两个函数意味着一个函数的结果将作为另一个函数的输入。因此,如果您有两个函数具有相同的输入类型和相同的输出类型,但输入和输出类型不同,则它们不能按任何顺序组合。
在您的特定情况下,您请求的组合函数将f1()
应用于f2()
的结果,但f2()
的结果是Integer
,而f1()
需要@ 类型的输入987654326@。解决该问题的一种方法是修改f1()
,使其在Integer
s 上运行:
Function<Integer, Integer> f1 = i -> i + 1;
Function<String, Integer> f2 = s -> Integer.valueOf(s) * 2;
Function<String, Integer> f3 = f1.compose(f2);
如果您无法修改f1()
,那么您可以在您的合成链中插入一个返回String
的中间转换:
Function<String, Integer> f1=s->Integer.valueOf(s)+1;
Function<String, Integer> f2 = s -> Integer.valueOf(s) * 2;
Function<String, Integer> f3 = f1.compose(f2.andThen(Integer::toString));
当然,所有这些来回转换到String
的成本都很高。
【讨论】:
【参考方案2】:函数组成“链”函数,函数本身具有结果类型。当然,您的具有不同输入类型和输出类型的函数不能在同一函数中“重用”。将 compose 视为按顺序执行功能:第一步:f2 中的字符串,输出为整数。然后 f1 中的 f2 的输出具有作为输入的字符串,而不是整数。因此,您的功能 compose 将不起作用。如果第一个函数的输出可以用作第二个函数的输入,则只能链接一个函数:
Function<Integer, Integer> f1 = i -> i + 1;
Function<String, Integer> f2 = s -> Integer.valueOf(s) * 2;
Function<String, Integer> f3 = f1.compose(f2);
【讨论】:
You can only chain a function if the output of the first function can be used as input of the second function
这一行让一切都清楚了!以上是关于为啥我不能用相同的参数类型组合两个不同的函数?的主要内容,如果未能解决你的问题,请参考以下文章
为啥不能用相同的签名声明两个方法,即使它们的返回类型不同? [复制]