我自动生成的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,但我无法找到通过自定义比较逻辑进行交叉的解决方案/示例。
任何想法都会有所帮助。
答案 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,或编写自己的行为以获得更多可自定义的行为。
来源:
答案 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
。