地图的比较不会产生正确的结果

时间:2015-02-04 11:11:26

标签: java hash hashmap

我有两个哈希映射finalOldCsv和finalNewCsv。这些映射存储从旧的和新的csv读取的值.Below是我的代码,用于查找常见行,仅来自旧csv的行和仅来自新csv的行。对于包含的新csv几千行,我的代码工作正常。但是当我尝试在一百万行的csv上执行相同的操作时。它产生错误的结果.code -

 private static void findDiff(LinkedHashMap<String, Integer> finalOldCsv,
            LinkedHashMap<String, Integer> finalNewCsv) {
        for(String test:finalOldCsv.keySet())
        {
        System.out.println("first row from old="+finalOldCsv.get(test));
        }
        for(String test1:finalNewCsv.keySet())
        {
        System.out.println("first row from new="+finalNewCsv.get(test1));

        }
         ArrayList<String>temp=new ArrayList<String>();
         for(String oldMatch : finalNewCsv.keySet())
         {
             if(oldMatch.contains(column[0]))
                 continue;
             else
             {
                 if (finalNewCsv.containsKey(oldMatch)&& finalOldCsv.containsKey(oldMatch))
                 {
                     System.out.println("Match Found");
                     writeCsv(writer,"Result/"+prefix+"_", oldMatch,"Common Rows");
                    temp.add(oldMatch);
                 }
             }
         }
         System.out.println("before old csv size="+finalOldCsv.size());
         for(String t:temp)
         {
         finalNewCsv.remove(t);
         finalOldCsv.remove(t);
         }
         System.out.println("after old csv size="+finalOldCsv.size());
         temp.clear();
         for(String newMatch : finalNewCsv.keySet())
           {
             if(newMatch.contains(column[0]))
            continue;
             else
             {
                 if (!finalOldCsv.containsKey(newMatch)&& finalNewCsv.containsKey(newMatch))
                 {
                 writeCsv(writer,"Result/"+prefix+"_", newMatch,"New Rows in New Table");
                 temp.add(newMatch);

                 }
             }

           }
         for(String t:temp)
         {
         finalNewCsv.remove(t);
         }
         temp.clear();
         System.out.println("finalOldCsv.keySet().size()"+finalOldCsv.keySet().size());
         for(String restFromOldTable:finalOldCsv.keySet())
         {
             if(restFromOldTable.contains(column[0]))
                 continue;
             else
                // if()
             writeCsv(writer,"Result/"+prefix+"_", restFromOldTable,"Rows from Old Table");
         }

    }

2 个答案:

答案 0 :(得分:1)

代码中似乎存在相当多的逻辑错误,我建议您解决然后重新发布:

  1. 您的代码遍历新密钥集,然后测试该条目是否在新密钥集中。这毫无意义。
  2. 删除所有常用行后,继续测试您考虑的密钥是否在两个集合中。没有必要进行这些测试。
  3. 事实上,在您删除了所有常见行后,您知道所有剩余行对于一组或另一组是唯一的。你根本不需要测试其他套件的成员资格。
  4. 所以最终得到3套 - 普通的,独特的旧的,独特的新的,你真的只需要:

    Set<String> common = oldMap.keySet().stream()
        .filter(k -> !k.equals(header))
        .filter(k -> newMap.keySet().contains(k)).collect(Collectors.toSet());
    Set<String> uniqueToOld = oldMap.keySet().stream()
        .filter(k -> !k.equals(header))
        .filter(k -> !common.contains(k)).collect(Collectors.toSet());
    Set<String> uniqueToNew = newMap.keySet().stream()
        .filter(k -> !k.equals(header))
        .filter(k -> !common.contains(k)).collect(Collectors.toSet());
    

    这样做的好处是不会更改已传递方法的地图。除非明确假设该方法正在改变它们,否则将它们作为算法的一部分进行更改是一个坏主意。

答案 1 :(得分:1)

我认为你做的比较复杂。 例如,当您在finalNewCsv语句中对if进行迭代时,您拥有此finalNewCsv.containsKey(oldMatch),这是不必要的,因为它始终是true

整个方法可以简化为:

Iterator<Map.Entry<String, Integer>> it = oldMan.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry<String, Integer> entry = it.next();
        if (newMap.containsKey(entry.getKey())) {
            it.remove();
            commonEntries.put(entry.getKey(), entry.getValue());
            newMap.remove(entry.getKey());
        }
    }

这样做是将oldMapnewMap中的所有类似密钥添加到commonEntries地图。我不完全确定这是findDiff()应该做的(该方法的名称具有误导性)。