How to use List of Functions in Java to compare two objects' fields and sum results

Viewed 78

I have two objects to compare field by field using a different function for every field from a list of functions.

Goal: call compare(NeedCompare n1, NeedCompare n2) using List of Functions and get an BigDecimal value = compareAmount(NeedCompare needCompare1, NeedCompare needCompare2) .add(compareValue(NeedCompare needCompare1, NeedCompare needCompare2) .add(compareName(NeedCompare needCompare1, NeedCompare needCompare2) .add(compareCategory(NeedCompare needCompare1, NeedCompare needCompare2)))))

Make it with streams would be perfect.

public class NeedCompare {
private BigDecimal category;
private String name;
private BigDecimal value;
private BigDecimal amount;

// The list is wrong and I don't know how to organize it
private List<Function<BigDecimal, NeedCompare>> functions = Arrays.asList(
        (needCompare1, needCompare2) -> compareCategory(needCompare1, needCompare2),
        (needCompare1, needCompare2) -> compareName(needCompare1, needCompare2),
        (needCompare1, needCompare2) -> compareValue(needCompare1, needCompare2),
        (needCompare1, needCompare2) -> compareAmount(needCompare1, needCompare2)

);

public BigDecimal compare(NeedCompare n1, NeedCompare n2) {
    //The method is broken. I need to return a sum of the results of the functions
    return functions.stream().map(function -> function(n1, n2)).reduce(BigDecimal.ZERO, BigDecimal::add);
}

private BigDecimal compareAmount(NeedCompare needCompare1, NeedCompare needCompare2) {
    // Complex function to compare category of NeedCompare
    return needCompare1.getCategory().equals(needCompare2.getCategory()) ? BigDecimal.ZERO : BigDecimal.ONE;
}

private BigDecimal compareValue(NeedCompare needCompare1, NeedCompare needCompare2) {
    // Complex function to compare name of NeedCompare
    return needCompare1.getName().equals(needCompare2.getName()) ? BigDecimal.ZERO : BigDecimal.ONE;
}

private BigDecimal compareName(NeedCompare needCompare1, NeedCompare needCompare2) {
    // Complex function to compare value of NeedCompare
    return needCompare1.getValue().equals(needCompare2.getValue()) ? BigDecimal.ZERO : BigDecimal.ONE;
}

private BigDecimal compareCategory(NeedCompare needCompare1, NeedCompare needCompare2) {
    // Complex function to compare amount of NeedCompare
    return needCompare1.getAmount().equals(needCompare2.getAmount()) ? BigDecimal.ZERO : BigDecimal.ONE;
}
// Getters and setters ...
1 Answers

The function you have take two parameters, so they are BiFunction<NeedCompare, NeedCompare, BigDecimal> (first come the types of the parameters, the return/target type is last). So you have private List<BiFunction<NeedCompare, NeedCompare, BigDecimal>> functions.

Also, you can simply and make the list a lot more readable by using method references instead of lambdas:

private List<BiFunction<NeedCompare, NeedCompare, BigDecimal>> functions 
    = Arrays.asList(this::compareCategory, this::compareName, 
        this::compareValue, this::compareAmount);
Related