繁体   English   中英

如何比较两个MultiMaps?

[英]How can I compare two MultiMaps?

我有两个Multimaps,它们是从两个巨大的CSV文件创建的。

Multimap<String, SomeClassObject> mapOne = ArrayListMultimap.create();
Multimap<String, SomeClassObject> mapTwo = ArrayListMultimap.create();

我假设一个CSV列作为密钥,每个密钥都有数千个与之关联的值。 这些Multimap包含的数据应该相同。 现在我想比较这些Multimap的数据,并查找是否有任何值不同。 以下是我想到的两种方法:

方法一:

Multimap一个大列表。 这个大清单将包含一些单独的清单。 每个较小的列表都包含一个唯一值,即从Multimap读取的“键”及其相关值,这些值将形成该单个列表的其余部分。

ArrayList<Collection<SomeClassObject>> bigList = new ArrayList<Collection<SomeClassObject>>();

bigList中将是单个小列表A,B,C等。

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

方法二:

比较Multimap但我不确定如何做到这一点。

哪种方法应该有更短的执行时间? 我需要在最短的时间内完成操作。

使用Multimaps.filterEntries(Multimap, Predicate)

如果要获得两个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);
}

在这个人为的例子中,输出是不在另一个列表中的元素:

{foo=[baz]}
{baz=[baz]}

如果地图匹配,这些多重映射将为空。


在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版本相同(具有相同的结果)。

ArrayListMultimap.equals doc:

将指定对象与此multimap进行相等性比较。

如果对于每个键,它们包含相同顺序的相同值,则两个ListMultimap实例是相等的。 如果值排序不一致,则多重映射将不被视为相等。

所以只需要mapOne.equals(mapTwo) 通过尝试自己完成,您将无法获得更好的执行时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM