首页 > 解决方案 > 在 java 8 中替换以下代码的优雅方法是什么?

问题描述

我的 java 程序中有以下代码(从实际程序中转述):

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;
    };
}

如评论中所述,我希望 matchObjects 方法在匹配条件之一失败后立即失败。此外,输入对象没有一一对应的关系来概括循环中的代码。

我有以下问题:

使用 java8 的函数式编程概念重写此代码的最佳方法是什么?

如果条件太多,我认为这里还有改进的余地。

我还编写了一个自定义谓词,它采用多个 &Optional参数来概括条件中属性等效性的测试if

然而,这并不能帮助我摆脱多种if情况。

请提前帮助和感谢。

标签: lambdajava-8

解决方案


你可以尝试这样的事情:

@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);
};

推荐阅读