如果您想获取两个Multimap
之间的差异,可以很容易地基于containsEntry
编写一个过滤器,然后使用过滤行为高效地查找所有不匹配的元素。只需基于一个映射构建Predicate
,然后过滤另一个映射即可。
这是我的意思。这里,我使用Java 8 lambdas,但您可以查看此帖子的修订历史记录以查看Java 7版本:
public static void main(String[] args) {
Multimap<String, String> first = ArrayListMultimap.create();
Multimap<String, String> second = ArrayListMultimap.create();
first.put("foo", "foo");
first.put("foo", "bar");
first.put("foo", "baz");
first.put("bar", "foo");
first.put("baz", "bar");
second.put("foo", "foo");
second.put("foo", "bar");
second.put("baz", "baz");
second.put("bar", "foo");
second.put("baz", "bar");
Multimap<String, String> firstSecondDifference =
Multimaps.filterEntries(first, e -> !second.containsEntry(e.getKey(), e.getValue()));
Multimap<String, String> secondFirstDifference =
Multimaps.filterEntries(second, e -> !first.containsEntry(e.getKey(), e.getValue()));
System.out.println(firstSecondDifference);
System.out.println(secondFirstDifference);
}
在这个人为构造的例子中,Output是不在另一个列表中的元素:
{foo=[baz]}
{baz=[baz]}
如果多个地图匹配,这些multimap将为空。
在Java 7中,您可以手动创建谓词,例如:
public static class FilterPredicate<K, V> implements Predicate<Map.Entry<K, V>> {
private final Multimap<K, V> filterAgainst;
public FilterPredicate(Multimap<K, V> filterAgainst) {
this.filterAgainst = filterAgainst;
}
@Override
public boolean apply(Entry<K, V> arg0) {
return !filterAgainst.containsEntry(arg0.getKey(), arg0.getValue());
}
}
将其作为参数传递给Multimaps.filterEntries()
,例如:
Multimap<String, String> firstSecondDifference =
Multimaps.filterEntries(first, new FilterPredicate(second));
Multimap<String, String> secondFirstDifference =
Multimaps.filterEntries(second, new FilterPredicate(first));
否则,代码与上面的Java 8版本相同(结果也相同)。