我似乎无法使其工作。Java 8 Lambda超载
Function<Integer, Integer> test = x -> x+x;
Function<String, String> test = x -> x+x;
产生
重复的局部变量
test
我怎样才能让这个test.apply(5)
收益10 test.apply("5")
回报“55”?
我似乎无法使其工作。Java 8 Lambda超载
Function<Integer, Integer> test = x -> x+x;
Function<String, String> test = x -> x+x;
产生
重复的局部变量
test
我怎样才能让这个test.apply(5)
收益10 test.apply("5")
回报“55”?
test
是一个变量,它不是一个方法。你不能重载一个变量。
您可能会尝试使用两个方法签名创建接口,但结果不会是功能接口,并且您无法使用lambda实现它。我们再次失败。
所以,无论如何,没有办法做'test.apply(5)'和'test.apply(“5”)'并得到我描述的行为在问题中? – SGr 2014-09-18 21:20:34
你可以,但绝对不能使用lambda来实现'test :: apply'。自定义界面的行人执行将是唯一的方法。 – 2014-09-18 21:21:04
简而言之:你不能。
你在做什么不是超载。它创建了两个不同的实例,其中包含冲突名称的界面。
这相当于做:
int a = 1;
int a = 2;
在同一范围内,同样是非法的。
超载会发生,如果你能在Function
接口两个apply
定义 - 一个以String
参数,一个以int
。你不能(轻易地)修改java中的现有接口。
您不能有一个test
变量实现Function<Integer, Integer>
和Function<String, String>
(这是相同的接口)的匿名函数。
但是,您可以使用重载apply
方法的嵌套类,并最终使用lambda函数构造它。这个嵌套类不需要(也不能)实现Function<Integer, Integer>
和Function<String, String>
。但作为显示在下面的例子中,你其实并不需要实现这些接口:
static class FunctionOverload {
private final Function<String, String> stringFunction;
private final Function<Integer, Integer> integerFunction;
FunctionOverload(Function<String, String> stringFunction, Function<Integer, Integer> integerFunction) {
this.stringFunction = stringFunction;
this.integerFunction = integerFunction;
}
public String apply(String string) {
return this.stringFunction.apply(string);
}
public Integer apply(Integer integer) {
return this.integerFunction.apply(integer);
}
}
public static void main(String[] args) {
FunctionOverload test = new FunctionOverload(x -> x + x, x -> x + x);
test.apply("5");
test.apply(5);
Stream.of("5").map(test::apply);
Stream.of(5).map(test::apply);
}
尽管你的代码上述问题试图“超载变量”可以做到这一点。快速而丑陋的解决方案如下:
@SuppressWarnings("unchecked")
public static <T> T addOrConcat(T x){
if (x instanceof String){
String ret = x.toString();
return (T)(ret + ret);
} else if (x instanceof Integer){
Integer ret = (Integer)x + (Integer)x;
return (T)(ret);
}
return null;
}
public static void main(String[] args) {
UnaryOperator<Object> test = x -> addOrConcat(x);
System.out.println(test.apply(Integer.valueOf(5)));
System.out.println(test.apply("5"));
}
输出将如下所示:
假以时日,我认为人们可以想出一些更有效的,更安全和直观。
在测试驱动开发的荣誉,我就可以把我的整个JUnit测试:
@Test
public void shouldWork() {
UnaryOperator<Object> test = x -> {
if (x instanceof Integer) {
int intValue = (Integer) x;
return intValue + intValue;
}
return x.toString() + x.toString();
};
Assert.assertEquals(10, test.apply(5));
Assert.assertEquals("55", test.apply("5"));
}
这是问题是一种面向对象编程和函数式编程的碰撞。
你不能,而问题是类型擦除。
您将需要一个单一的对象,既是Function<Integer, Integer>
和Function<String, String>
,所以它有两个apply
方法:
class MyFunc implements Function<Integer, Integer>, Function<String, String> {
public Integer apply(Integer v) { return x + x; }
public String apply(String v) { return x + x; }
}
然而,Java编译器不可能编译这是因为字节码不具备泛型的概念,所以这两个接口将是相同的,难以区分的。
而不是使用函数你可以简写为UnaryOperator –
TechTrip
2014-09-18 22:05:46