【问题标题】:How to compare the values of 2 Maps Java如何比较 2 Maps Java 的值
【发布时间】:2015-11-14 18:36:59
【问题描述】:

在高层次上,我正在尝试比较 2 个字符串映射的值

Map 1: [{ExpID1, SomeExpValue1}, {ExpID2, SomeExpValue2}, ...]

Map 2: [{FriID1, SomeFriValue1}, {FriID1, SomeFriValue2}, ...]

所以最终,我希望我的比较是这样的:

须藤代码:

if ( ExpID1.equals(FriID1) ) {
    Assert.AssertEquals(SomeExpValue1, SomeFriValue1, "Library element does not match!")
}

但是,由于这些是地图,因此需要进行一些循环。我真正的问题在这里,我怎样才能正确有效地循环没有更多的嵌入式 foreach 或 forloops。这些似乎超级昂贵。我觉得我当前的循环在某种程度上是错误的或非常昂贵。任何帮助或帮助将不胜感激。

目前我拥有的是这样的:

@Test
public void testIntegration() throws Exception {

    // Get all files in directory
    File[] files = getFilesInFolder(friendlyNamesDir);

    String linkedResp = FileUtils.readFileToString(new File(explanationResponsePath));
    Map<String, String> map1 = getIDTitleMapExpResponse(linkedResp, "node");

    int counter = 1;
    for(File f : files) {
        if(f.length() == 0) throw new Exception("File does not exist...");


        for(String expID : map1.keySet()) {
            logger.info("Exp ID: "+expID);

            Map<String, String> map2 = getIDNameMapFromFriendly(f.getCanonicalPath());
            for(String friendlyID : map2.keySet()) {
                logger.info(counter+" - Friendly ID: "+friendlyID+" Name: "+map2.get(friendlyID));
                if(friendlyID.equals(expID)) {
                    Assert.assertEquals(map1.get(friendlyID), map2.get(expID));
                }
                counter++;
            }
        }
    }
}

【问题讨论】:

  • map的key集合的交集就是要迭代的集合,如果map 1的值和map 2的值相等,那么对于所有的迭代值,你的条件都是true。 (我知道地图 1 中可能有键,而不是地图 2,反之亦然。如果没有,请澄清。)
  • @laune 是的,总结得差不多了。我想单独比较地图的值,因此是 foreach 循环。
  • 好的,所以我认为这不仅仅是 map1.equals(map2)...
  • 我要做的是循环遍历 2 个地图的 ID,如果 map1 的当前 ID 与 map2 匹配,则比较它们的值(断言它们相等)

标签: java data-structures collections compare assert


【解决方案1】:

根据 Java 文档:
https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#equals-java.lang.Object-

您可以直接比较地图,它会确保检查其中的元素是否相等。

【讨论】:

    【解决方案2】:

    我了解映射不一定相等,但必须包含相等键的相等值。因此:

    boolean alleq = true;
    Set<String> key1 = new HashSet<>( map1.keySet() );
    key1.retainAll( map2.keySet();
    for( String s: key1 ) ){
         if( ! map1.get(s).equals( map2.get(s) ) ){
              alleq = false;
              break;
         }
    }
    

    您还可以迭代一个密钥集并测试另一个密钥集中是否存在;无需迭代第二组。

    boolean alleq = true;
    for( String key1: map1.keySet() ){
        String value2 = map2.get( key1 );
        if( value2 != null && ! value2.equals( map1.get(key1) ) ){
            alleq = false;
            break;
        }
    }
    

    【讨论】:

    • 我不确定这是否是合法的 Java,因为 map1.keySet().retainAll(map2.keySet()) 返回一个布尔类型
    • @mosawi Drat。函数式编程...已修复。但是您知道我的意思 - 这应该可以相对有效地解决您的问题,尽管迭代一张地图的键并检查另一张地图并不是很糟糕。
    • 啊,很好地使用retainAll...这解决了我的问题,我想我刚刚学会了如何使用retainAll :)
    • 如果我要在 foreach 循环中打印当前元素(可迭代 key1 的 s 元素),会打印什么?据我了解,key1 包含了map1 和map2 的所有匹配键,那么key1 的s 是否应该打印出所有匹配的键(大部分应该匹配)?我只看到打印出大约 10 个相同键的键?这是否意味着只有 10 个键匹配? map1 和 map2 中有数百个键,因为我们正在循环多个文件。
    • 一旦发现某个键的值不匹配,循环就会终止。如果您需要知道匹配键的数量与匹配键的匹配值的数量,则必须省略中断,区分这两种情况并计算两者。
    猜你喜欢
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    • 2020-07-19
    相关资源
    最近更新 更多