如何比较两个MultiMaps? [英] How can I compare two MultiMaps?

查看:131
本文介绍了如何比较两个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 Multimaps should be same. Now I want to compare the data within these Multimaps 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 Multimaps 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 Multimaps, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆