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

查看:35
本文介绍了如何比较两个 MultiMap?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个 Multimap,它们是从两个巨大的 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.

我计划在检查第二个 Multimap 中的单个列表包含该key"元素的基础上,从两个文件的每个 bigList 中选取单个列表.如果是,则比较这两个列表并找出无法匹配的任何内容.

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写一个过滤器很容易,然后利用过滤行为高效地找出所有不匹配的元素.只需根据一张地图构建Predicate,然后过滤另一张.

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() 的参数,如下所示:

Use it as an argument to Multimaps.filterEntries() like this:

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.

这篇关于如何比较两个 MultiMap?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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