考虑一些字段,检查JAXB对象的等于

时间:2013-08-07 15:41:24

标签: java collections guava

我自动生成的JAXB类

public class Employee {
   private int id;
   private String name;
   private String department;

   /* Getters and Setters */

}

Employee emp1 = new Employee();
emp1.setId(1);
emp1.setName("A");
emp1.setDepartment("D1");


Employee emp2 = new Employee();
emp2.setId(2);
emp2.setName("B");
emp2.setDepartment("D1");

List<Employee> empList1 = new ArrayList<Employee>();
empList1.add(emp1);
empList2.add(emp2);

Employee emp3 = new Employee();
emp2.setId(3);
emp2.setName("A");
emp2.setDepartment("D1");

List<Employee> empList2 = new ArrayList<Employee>();
empList2.add(emp3);
  

我想比较列表empList1和empList2,并获得一个与Employee对象的名称和部门字段匹配的结果列表。

基本上,我需要基于两个对象中字段的自定义比较两个列表的交集。

我正在查看Google Guava和lambdaJ,但我无法找到通过自定义比较逻辑进行交叉的解决方案/示例。

任何想法都会有所帮助。

3 个答案:

答案 0 :(得分:2)

为了进行比较,您可以使用Guava Ordering或Java Comparator。对于过滤,您可以使用谓词。

如果你想要一般的东西你可以使用make一个比较器(对于DEP和NAME)

    class MyComparator implements Comparator<Employee> {

        @Override
        public int compare(final Employee left, final Employee right) {
            return ComparisonChain.start().compare(left.getName(), right.getName())
                                  .compare(left.getDepartment(), right.getDepartment()).result();
        }

    }

    class MyPredicate implements Predicate<Employee> {

        final List<Employee> employees;
        final Comparator<Employee> comparator;

        public MyPredicate(final List<Employee> employees, final Comparator<Employee> comparator) {
            this.employees = employees;
            this.comparator = comparator;
        }

        @Override
        public boolean apply(@Nullable final Employee input) {
            for (final Employee e : employees) {
                if (comparator.compare(e, input) == 0) {
                    return true;
                }

            }

            return false;
        }

    }

然后你可以像这样使用它:

    final MyComparator comparator = new MyComparator();
    final MyPredicate predicate1 = new MyPredicate(empList1, comparator);
    final MyPredicate predicate2 = new MyPredicate(empList2, comparator);
    System.out.println("####");
    System.out.println(Collections2.filter(empList2, predicate1));
    System.out.println(Collections2.filter(empList1, predicate2));

答案 1 :(得分:0)

public List<Employee> findIntersections(List<Employee> listA, List<Employee> listB)
{

    List<Employee> returnList = new List<Employee>();
    Employee empA, empB;

    for(int i = 0; i<listA.size; i++)
    {
        for(int j = 0; j<listB.size; j++)
        {
            empA = listA.get(i);
            empB = listB.get(j);

            if(empA.getID == empB.getID() && empA.getName().equals(empB.getName()) && empA.getDepartment().equals(empB.getDepartment()))
            {
                returnList.add(empA);//or add empB...since theyre the same
            }
        }
    }

    return returnList;
}
  

我想要一个通用的实现。有很多JAXB对象   要求基于字段的相等检查。是否有类似的东西   比较器有一个返回布尔值的方法?

这是我发现的(你可能需要一个插件):

  

不幸的是,jaxb没有提供开箱即用的功能。您可以使用   这个plugin,或编写自己的行为以获得更多可自定义的行为。

来源:

https://stackoverflow.com/a/7771776/2498729

答案 2 :(得分:0)

手动破解方法以交叉两个列表将是最快的方法。但是,如果你需要一个更普遍的aproache用于Employee以外的其他东西,例如你可以使用guavas Equivalence类。有了它,您可以将列表中的条目映射到Equivalence.Wrapper,并在这些Wrappers集上使用Sets.intersect

public static <T> Set<T> intersect(Iterable<? extends T> a, Iterable<? extends T> b, Equivalence<? super T> eq) {
    Function<T, Wrapper<T>> f = wrappingFunction(eq);

    Set<Wrapper<T>> as = ImmutableSet.copyOf(Iterables.transform(a, f));
    Set<Wrapper<T>> bs = ImmutableSet.copyOf(Iterables.transform(b, f));

    SetView<Wrapper<T>> intersection = Sets.intersection(as, bs);

    return ImmutableSet.copyOf(Iterables.transform(intersection,
            Test.<T> unwrappingFunction()));
}

其中wrappingFunction()unwrappingFunction()有两个效用函数:

    public static <T> Function<T, Wrapper<T>> wrappingFunction(
        final Equivalence<? super T> eq) {
    return new Function<T, Wrapper<T>>() {
        public Wrapper<T> apply(T input) {
            return eq.wrap(input);
        }
    };
}

private static final Function<Wrapper<Object>, Object>  UNWRAPPING_FUNCTION = new Function<Wrapper<Object>, Object>() {

    public Object apply(Wrapper<Object> input) {
        return checkNotNull(input).get();
    }
};

@SuppressWarnings("unchecked")
public static <T> Function<Wrapper<T>, T> unwrappingFunction() {
    return ((Function<Wrapper<T>, T>) ((Function<?, ?>) UNWRAPPING_FUNCTION));
}

有了这个,你必须为Equivalence实施Employee并申请intersect

Set<Employee> x = intersect(a, b, new Equivalence<Employee>() {

        @Override
        protected boolean doEquivalent(Employee a, Employee b) {
            checkNotNull(a);
            checkNotNull(b);
            return Objects.equals(a.getId(), b.getId())
                && Objects.equals(a.getDepartment(), b.getDepartment())
                && Objects.equals(a.getName(), b.getName());
        }

        @Override
        protected int doHash(Employee t) {
            return t.getId();
        }
    });

在此示例中,返回的Set不会包含重复的Employees