Reputation: 961
I have the following code in my java program (paraphrased from the actual program):
import java.util.Objects;
import java.util.function.BiPredicate;
class Class1 {
String propertyA;
boolean propertyANot;
String propertyB; //Not all members have corresponding negate indicator
String propertyC;
String propertyD;
boolean propertyDNot;
....
}
class Class2 {
String propertyX;
String propertyY;
String propertyZ;
String propertyW;
....
}
public class Main {
//Fail early without inspecting all properties
private BiPredicate<Class1,Class2> matchObjects = (obj1,obj2) -> {
if(obj1.propertyA != null && obj2.propertyX != null) {
//property1Not is a boolean indicates negation
if(obj1.propertyANot && !Objects.equals(obj1.propertyA,obj2.propertyX)) {
return false;
}
else if(!obj1.propertyANot && Objects.equals(obj1.propertyA,obj2.propertyX)) {
return false;
}
}
if(obj1.propertyB != null && obj2.propertyY != null) {
if(!Objects.equals(obj1.propertyB,obj2.propertyY)) {
return false;
}
}
....
return true;
};
}
As indicated in the comments, I want the matchObjects method to fail as soon as one of the matching conditions fail. Also the input objects don't have one-to-one correspondence to generalize the code in a loop.
I have following question:
What's the best way to rewrite this code using functional programming concepts of java8?
Having too many if conditions are making me think there is a scope for improvement here.
I also wrote a custom predicate that takes multiple & Optional
parameters to generalize the testing of property equivalence in the if
conditions.
However this is not helping me to get rid of multiple if
conditions.
Please help & thanks in advance.
Upvotes: 1
Views: 145
Reputation: 4813
You can try something like this:
@FunctionalInterface interface TriPredicate<A, B, C> {
boolean test (A a, B b, C c);
}
private BiPredicate<Class1, Class2> matchObjects = (obj1, obj2) -> {
TriPredicate<String, String, Boolean> matchProp = (propA, propX, cond) ->
propA == null && propX == null ||
(cond == null || cond) == Objects.equals(propA, propX);
return matchProp.test(obj1.propertyA, obj2.propertyX, obj1.propertyANot) &&
matchProp.test(obj1.propertyB, obj2.propertyY, null) &&
matchProp.test(obj1.propertyC, obj2.propertyZ, null) &&
matchProp.test(obj1.propertyD, obj2.propertyW, obj1.propertyDNot);
};
Upvotes: 3