您在问题中提供的示例与 Java 8 无关,而是与泛型在 Java 中的工作方式有关。 Function<T, Integer> function 和Function<T, Double> function 在编译时会经过type-erasure 并转换为Function。方法重载的经验法则是具有不同数量、类型或顺序的参数。由于您的两种方法都将转换为采用 Function 参数,因此编译器会抱怨它。
话虽如此,srborlongan 已经提供了一种解决问题的方法。该解决方案的问题在于,您必须针对不同类型(整数、双精度等)的每种操作(加法、减法等)不断修改您的 Test 类。另一种解决方案是使用method overriding 而不是method overloading:
将Test 类更改如下:
public abstract class Test<I,O extends Number> {
List<I> list = new ArrayList<>();
public O performOperation(Function<I,O> function) {
return list.stream().map(function).reduce((a,b)->operation(a,b)).get();
}
public void add(I i) {
list.add(i);
}
public abstract O operation(O a,O b);
}
创建一个Test 的子类,它将添加两个Integers。
public class MapStringToIntAddtionOperation extends Test<String,Integer> {
@Override
public Integer operation(Integer a,Integer b) {
return a+b;
}
}
然后客户端代码可以使用上面的代码如下:
public static void main(String []args) {
Test<String,Integer> test = new MapStringToIntAddtionOperation();
test.add("1");
test.add("2");
System.out.println(test.performOperation(Integer::parseInt));
}
使用这种方法的好处是你的Test类符合open-closed的原则。要添加诸如乘法之类的新运算,您所要做的就是添加Test 和override 的新子类operation 方法来将两个数字相乘。将其与Decorator 模式结合使用,您甚至可以最大限度地减少必须创建的子类的数量。
注意此答案中的示例是指示性的。有很多改进的领域(例如将Test 设为函数式接口而不是抽象类)超出了问题的范围。