Java:通用函数引用的编译错误

时间:2018-01-10 20:30:45

标签: java generics lambda java-8 method-reference

有人可以帮我解决这个编译错误吗?

我想在名为Suite的通用界面中定义一个map方法,并像这样使用它:

Suite < Integer > suite2 = Suite.from("34", "78", "23").map(Integer::parseInt);

assertEquals(3, suite.size());
assertEquals(34, (int)suite.get(0));
assertEquals(78, (int)suite.get(1));
assertEquals(23, (int)suite.get(2));

使用函数和参数调用相同的方法编译得很好:

Suite<Integer> suite1 = Suite.from(1, 2).map(x -> x * 2);

assertEquals(2, suite.size());
assertEquals(2, (int)suite.get(0));
assertEquals(4, (int)suite.get(1));

所以我已经在界面中定义了这个方法

public interface Suite<E> {

    public <E> Suite<E> map(int i, Function<? super E, ? extends E> f);
}

注意:这与Stream类的map方法几乎相同  (除了参数i)

我的问题出在我的测试中,这行不编译:

map(Integer::parseInt)

因为这些错误:

  
      
  • Integer类型未定义此处适用的toString(Object)
  •   
  • 类型不匹配:无法将Suite<Object>转换为Suite<String>
  •   

我尝试使用Supplier<E>重新定义该功能,但它不起作用。

2 个答案:

答案 0 :(得分:2)

 Function<? super E, ? extends E> function

Integer不是String的超类,因此失败:

Suite <String> suite1 = Suite.span(1, Integer::toString);

参考:Difference between <? super T> and <? extends T> in Java

答案 1 :(得分:2)

通常功能映射需要改变类型,例如参数和结果类型是分歧的:

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#map-java.util.function.Function-

  

套房&lt;整数&gt; suite2 = Suite.from(&#34; 34&#34;,&#34; 78&#34;,&#34; 23&#34;)。map(Integer :: parseInt);

此处您将String类型更改为Integer,因此您无法使用常见的E通用名称,例如

public <E> Suite<E> map(int i, Function<? super E, ? extends E> f);

但:

public <T, R> Suite<R> map(int i, Function<? super T, ? extends R> f);

或:

public interface Suite<E> {
    public <R> Suite<R> map(int i, Function<? super E, ? extends R> f);
}