将n个对象的多个字段与常见值进行比较

时间:2016-02-19 20:29:35

标签: java mysql spring hibernate comparator

基本上我有一个表单,我必须根据对象id选择的常用字段值进行预填充。例如。我有4个字段的对象(a,b,c,d,可能更多)。如果选择了ids 1,2,3(可能超过3个)的对象,我应该如何比较每个所选对象的所有字段,以便使用常用值预填充表单?

我已经查看了Comparator类,但看起来它一次比较两个对象(可能是多个字段),这意味着如果我选择了n个对象,它可能意味着很多循环?

我还考虑过使用distinct进行sql select,然后根据返回的行数我会知道字段值是否相同。然而,这意味着我必须进行尽可能多的sql不同调用,因为有些字段听起来也很麻烦,以及我在数据库而不是应用程序中做逻辑的事实......

我正在使用hibernate,spring和java,所以我想知道我是否只是缺少一个可以为此做类似事情的功能?

目前我正在使用像

这样的东西
CollectionUtils.collect(objectList,TransformerUtils.invokerTransformer("getA")); 

并为每个表单字段执行此操作,然后检查数组中是否有重复值,这些值看起来都不是最佳...

任何帮助/提示都将不胜感激!

1 个答案:

答案 0 :(得分:0)

以下是使用Java 8流的方法:

public class Test8 {
    public static void main(String[] args) {
        MyObj[] testData = {
                new MyObj(1, "X", 3.14, "Larry"),
                new MyObj(2, "X", 3.14, "Curly"),
                new MyObj(3, "X", 3.14, "Moe"),
        };
        System.out.println("A = " + findCommon(testData, MyObj::getA).orElse(null));
        System.out.println("B = " + findCommon(testData, MyObj::getB).orElse(null));
        System.out.println("C = " + findCommon(testData, MyObj::getC).orElse(null));
        System.out.println("D = " + findCommon(testData, MyObj::getD).orElse(null));
    }
    private static <T, R> Optional<R> findCommon(T[] data, Function<? super T, ? extends R> getterMethod) {
        Set<R> values = Arrays.stream(data)
                              .map(getterMethod)
                              .collect(Collectors.toSet());
        return (values.size() == 1
                ? Optional.ofNullable(values.iterator().next())
                : Optional.empty());
    }
}
class MyObj {
    private final int    a;
    private final String b;
    private final double c;
    private final String d;
    MyObj(int a, String b, double c, String d) {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }
    public int getA() {
        return this.a;
    }
    public String getB() {
        return this.b;
    }
    public double getC() {
        return this.c;
    }
    public String getD() {
        return this.d;
    }
}

<强>输出

A = null
B = X
C = 3.14
D = null

<强>更新

使用Set是一个简单的解决方案,但它始终必须扫描所有对象。

如果您有许多对象,一旦找到不同的值,立即停止扫描可能会对性能有所帮助:

private static <T, R> Optional<R> findCommon(T[] data, Function<? super T, ? extends R> getterMethod) {
    R onlyValue = null;
    for (T obj : data) {
        R value = getterMethod.apply(obj);
        if (value == null)
            return Optional.empty();
        if (onlyValue == null)
            onlyValue = value;
        else if (! value.equals(onlyValue))
            return Optional.empty();
    }
    return Optional.ofNullable(onlyValue);
}