一个接受通配符列表和函数的函数?

时间:2014-12-07 00:44:29

标签: java java-8

我有一个接受通配符列表的方法,但也接受java.util.function.Function的实现,该实现接受列表包含的相同类型的元素并返回String。要做到这一点,我有两个想法,但它们都不令人满意。

方法1:使方法通用。

public <T> void method(List<T> list, Function<T, String> function){
    ...
}

方法2:让Function的第一个类型成为通配符?

public void method(List<?> list, Function<?, String> function){
    ...
}

我不喜欢方法1,我甚至不确定方法2是否有效,因为有时我会得到如下的奇怪错误:

error: incompatible types: Object cannot be converted to CAP#1
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?

我是否有另一种方法可以在不离开Function参数原始的情况下创建这样的方法?

2 个答案:

答案 0 :(得分:4)

使用方法的 wildcast 版本

public void method(List<?> list, Function<?, String> function)

是不可能的,因为 - 正如您已经注意到的那样 - 不可能使用Wildcast作为变量的类型。

使用泛型类型参数还有另外一种方法。你可以尝试使用

public void method(List<Object> list, Function<Object, String> function)

作为方法的签名,如果你真的想要使用包含多个类的实例的列表list

但是,如果你只想允许一种类型的元素,你肯定必须使用泛型,所以你的方法必须看起来像你已经在你的问题中显示的那样:

public <T> void method(List<T> list, Function<T, String> function)

如果你的问题是如何调用你的方法,以防你使用泛型,那很简单。说,你有List<Integer> list。如果您再调用method(list,...),则list的泛型类型会自动确定function的第一个类型参数,在这种情况下,function必须是{{1}的实例}}。因为你想使用lambda表达式来调用方法,比如

Function<Integer, String>

完全正确。

答案 1 :(得分:0)

这是一个疯狂的猜测,但我认为问题在于:

public void method(List<?> list, Function<?, String> function){
    ...
}

您可能假设签名中的两张外卡都属于同一类型。尝试这样的事情:

public <T> void method(List<T> list, Function<T, String> function){
    ...
}