java 8 map reduce,执行map-reduce操作的通用方法。 (爪哇-8)

本文探讨了如何在Java 8中使用泛型参数实现函数重载,展示了两种方法:标准的重载方式遇到冲突,随后提出使用抽象基类和子类实现的策略,遵循开放-封闭原则,以避免频繁修改。通过实例演示了如何利用这个方法添加不同操作(如加法、乘法)。
摘要由CSDN通过智能技术生成

How to overload a Function with generic parameter in Java 8?

public class Test {

List list = new ArrayList<>();

public int sum(Function function) {

return list.stream().map(function).reduce(Integer::sum).get();

}

public double sum(Function function) {

return list.stream().map(function).reduce(Double::sum).get();

}

}

Error: java: name clash:

sum(java.util.function.Function) and

sum(java.util.function.Function) have the same erasure

解决方案

The example you present in your question has got nothing to do with Java 8 and everything to do with how generics work in Java. Function function and Function function will go through type-erasure when compiled and will be transformed to Function. The rule of thumb for method overloading is to have different number, type or sequence of parameters. Since both your methods will transform to take a Function argument, the compiler complains about it.

That being said, srborlongan has already provided one way to resolve the issue. The problem with that solution is that you have to keep modifying your Test class for each and every type of operation (addition,subtraction,etc) on different types (Integer,Double, etc). An alternate solution would be to use method overriding instead of method overloading :

Change the Test class a bit as follows :

public abstract class Test {

List list = new ArrayList<>();

public O performOperation(Function 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 Integers.

public class MapStringToIntAddtionOperation extends Test {

@Override

public Integer operation(Integer a,Integer b) {

return a+b;

}

}

Client code can then use the above code as follows :

public static void main(String []args) {

Test 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 in line with the open-closed principle. To add a new operation such as multiplication, all you have to do is add a new subclass of Test and override the operation method to multiply two numbers. Club this with the Decorator pattern and you can even minimize the number of sub-classes that you have to create.

Note The example in this answer is indicative. There are a lot of areas of improvement (such as make Test a functional interface instead of an abstract class) which are beyond the scope of the question.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值