2016-02-19 51 views
0

基本上我有一种形式,我必须根据对象id选择的公共字段值预先填充。例如。我有4个领域的对象(a,b,c,d,可能更多)。如果选择了ids 1,2,3(可能超过3个)的对象,那么我应该如何比较每个选定对象的所有字段,以便预先填充具有共同值的表单?比较共同值的n个对象的多个字段

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

我也考虑做一个SQL选择不同,然后基于返回的行数我会知道如果字段值是否相同。然而,这意味着我必须做出尽可能多的SQL不同的调用,因为有领域这也听起来很麻烦,以及我会做数据库中的逻辑而不是应用程序的事实...

我是使用休眠,春天和Java所以我想知道如果我只是缺少一个功能,可以做类似的事情?

目前我使用的是类似

CollectionUtils.collect(objectList,TransformerUtils.invokerTransformer("getA")); 

,做它为每个窗体域,然后检查重复值的阵列,它似乎并不在最佳所有要么...

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

+0

不清楚你想要做什么。 “比较”和“预填充”如何结合在一起?您是否试图在数据库中以字段为单位预填表格中最常见的值? – Andreas

+0

你可以编写你自己的比较器,它有'n'方法作为你需要比较的属性数量。我认为这是针对您的问题的简单解决方案。不要忘记,如果你有'm'对象,那么你将有'm'次验证。 – aribeiro

+0

@Andreas是的,我试图预填充表单,只有当所有选择的对象都为该字段保留相同的值(所以表单可能有一些预填充的值,并为其他人留空)由于不清楚! – ec3

回答

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 

UPDATE

使用Set是一个简单的解决方案,但它总是有t o扫描所有对象。

如果你有很多的对象,它可能是很好的性能为您找到不同的值,一旦停止扫描:

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); 
} 
+0

我认为这可能完美/可能比我以前的方法更优化。除了流之外,它看起来像我们去类似的(我也使数组到一个集来检查大小== 1)没有读取array.steam,但它是有益的,因为我不需要为每个字段实例化一个数组?将尝试实施并报告。谢谢!! – ec3