Is it possible to do this using Predicate interface.
I have a client class that utilizes functions provided by a MathUtility class. Whatever the Mathmatical operation it should happen only within the MathUtility class.
//in client
MathUtility.sum(listOfInts, (Integer i)->{return (i<3);});
//in utility
class MathUtility {
public static T sumWithCondition(List numbers, Predicate condition) {
return numbers.parallelStream()
.filter(condition)
.map(i -> i)
.reduce(0, T::sum); //compile time error
}
public static T avgWithCondition(List numbers, Predicate condition) {
//another function
}
//lot many functions go here
}
Right now it fails with this error - The method reduce(T, BinaryOperator) in the type Stream is not applicable for the arguments (int, T::sum)
Note: I do not want to write sum functions for different Number types
解决方案
Is there a way to do it without writing a sum function for every possible type of T that i'm expecting?
As Aaron Davis stated in a comment above, you can pass the reduction parameters to the method itself.
public static T sumWithCondition(List numbers, Predicate condition, T identity, BinaryOperator accumulator) {
return numbers.parallelStream().filter(condition).reduce(identity, accumulator);
}
An example would be:
List list = Arrays.asList(1, 2, 3, 4, 5);
System.out.println(sumWithCondition(list, i -> i > 1, 0, (a, b) -> a + b));
>> 14
List list2 = Arrays.asList(BigInteger.ONE, BigInteger.ONE);
System.out.println(sumWithCondition(list2, i -> true, BigInteger.ZERO, (a, b) -> a.add(b)));
>> 2