如何比较两个MultiMaps? [英] How can I compare two MultiMaps?
问题描述
我有两个Multimaps,它们是从两个巨大的CSV文件创建的。
I have two Multimaps which have been created from two huge CSV files.
Multimap<String, SomeClassObject> mapOne = ArrayListMultimap.create();
Multimap<String, SomeClassObject> mapTwo = ArrayListMultimap.create();
我假设有一个CSV列作为密钥,每个密钥都有数千个值关联用它。这些 Multimap
中包含的数据应该相同。现在我想比较这些 Multimap
中的数据,并查找是否有任何值不同。以下是我想到的两种方法:
I have assumed one CSV column to be as a Key and each of the Key has thousands of values associated with it. Data contained within these Multimap
s should be same. Now I want to compare the data within these Multimap
s and find if any values are different. Here are the two approaches I am thinking of:
方法一:
从 Multimap
中创建一个大清单。这个大清单将包含一些单独的清单。每个较小的列表都包含一个唯一值,即从 Multimap
中读取的键及其相关值,这些值将构成该单个列表的其余部分。
Make one big list from the Multimap
. This big list will contain a few individual lists. Each of the smaller lists contains a unique value which is the "key" read from Multimap
along with its associated values, which will form the rest of that individual list.
ArrayList<Collection<SomeClassObject>> bigList = new ArrayList<Collection<SomeClassObject>>();
bigList
将是个别小清单A ,B,C等。
Within bigList
will be individual small lists A, B, C etc.
我计划在两个文件的每个 bigList
中挑选单个列表检查来自第二个 Multimap
的个别列表包含该key元素。如果是,则比较这两个列表并找到任何无法匹配的内容。
I plan on picking individual lists from each bigList
of the two files on the basis of checking that individual list from second Multimap
contains that "key" element. If it does, then compare both of these lists and find anything that could not be matched.
方法二:
比较 Multimap
,但我不确定如何完成。
Compare both the Multimap
s but I am not sure how will that be done.
哪种方法应该有更短的执行时间?我需要在最短的时间内完成操作。
Which approach should have smaller execution time? I need the operation to be completed in minimum amount of time.
推荐答案
使用 Multimaps.filterEntries(Multimap,Predicate)
。
如果你想获得两个 Multimap
之间的差异,很容易编写基于 containsEntry
的过滤器,然后使用过滤行为有效地找到所有不匹配的元素。只需根据一张地图构建谓词
,然后过滤另一张。
Use Multimaps.filterEntries(Multimap, Predicate)
.
If you want to get the differences between two Multimap
s, it's very easy to write a filter based on containsEntry
, and then use the filtering behavior to efficiently find all the elements that don't match. Just build the Predicate
based on one map, and then filter the other.
这就是我的意思。在这里,我使用的是Java 8 lambdas,但你可以查看这篇文章的修订历史,看看Java 7版本:
Here's what I mean. Here, I'm using Java 8 lambdas, but you can look at the revision history of this post to see the Java 7 version:
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 is the element that is not in the other list, in this contrived example:
{foo=[baz]}
{baz=[baz]}
如果地图匹配,这些多重映射将为空。
These multimaps will be empty if the maps match.
在Java 7中,您可以使用以下内容手动创建谓词:
In Java 7, you can create the predicate manually, using something like this:
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版本相同(结果相同)。
Otherwise, the code is the same (with the same result) as the Java 8 version above.
这篇关于如何比较两个MultiMaps?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!