手动破解一个方法来交叉两个列表将是最快的方法。但是,如果您需要更通用的方法来处理 Employee 以外的其他内容,例如,您可以使用番石榴 Equivalence 类。这样,您可以将列表中的条目映射到 Equivalence.Wrapper 并在这些包装集上使用 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));
}
有了这个,您必须为Employee 实施Equivalence 并应用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。