The example you present in your question has nothing to do with Java 8 and it all depends on how generics work in Java. Function<T, Integer> function and Function<T, Double> function will go through type-erasure at compilation and will be converted to Function . A rule of thumb for method overloading is to have a different number, type, or sequence of parameters. Since both methods are converted to accept a Function argument, the compiler complains about this.
At the same time, srborlongan has already provided one way to solve the problem. The problem with this solution is that you must continue to modify your Test class for each type of operation (addition, subtraction, etc.) For different types (Integer, Double, etc.). An alternative solution would be to use method overriding instead of method overloading :
Modify the Test class as follows:
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); }
Create a subclass of Test that will add two Integer s.
public class MapStringToIntAddtionOperation extends Test<String,Integer> { @Override public Integer operation(Integer a,Integer b) { return a+b; } }
Client code can then use the code above as follows:
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)); }
The advantage of using this approach is that your Test class is open-closed . To add a new operation, such as multiplication, all you have to do is add a new subclass of Test and an override the operation method to multiply the two numbers. Create this with the Decorator template, and you can even minimize the number of subclasses you need to create.
Note The example in this answer is indicative. There are many areas of improvement (for example, making Test functional interface instead of an abstract class) that go beyond the scope of the question.