如何比较 Map 和 List

How to compare Map with List

对不起,我找不到更好的标题,而且我知道这听起来很混乱。 问题如下:

我有一个 HashMap,如下所示:

Map<String, ClassA> myMap;

此外,我有一个如下所示的列表:

List<ClassB> myList;

B 类如下所示:

   public class ClassB{

    //many things

    private String someString;
    //getter
    //setter
    }
}

someString 是关键字符串myMap

我想从地图中删除所有我在列表myList中找不到的objects,迭代次数最少,因为这种清理每隔几秒就会发生一次一生一世。

有算法吗?模式甚至示例?

谢谢

您必须至少迭代 List<ClassB> myList 一次才能这样做,但您可以精确地进行一次迭代,这使其成为理想的算法。

创建一个新地图,并为列表中的每个元素检查它是否在 myMap 中,如果存在 - 将其添加到您创建的新地图中。完成迭代列表后,只需分配:myMap = newMap; 就大功告成了。

注意:这是最少步数的理想选择,但它比"in-place"算法使用更多内存。

有java 8 流API,

Set<String> keySet = new HashSet<>(myMap.keySet());
myList.forEach(entry -> keySet.remove(entry.getSomeString()));
keySet.forEach(key -> myMap.remove(key));

就是这样。我刚刚所做的只是从 keySet 中删除了列表中的键。然后,我删除所有剩下的键。这将在 O(n).

中 运行

这将比当前解决方案消耗更少的内存,因为您要创建一个额外的 Set 而不是 Map

看起来你想要 retainAll。诀窍是您在地图的 keySet() 上调用它,它具有从地图中删除不需要的条目的副作用。

接下来,您想要保留的元素不在 List<ClassB> 中,而是在从 ClassB 的每个实例派生的字符串列表中。您可以使用流来做到这一点。

    myMap.keySet()
         .retainAll(myList.stream()
                          .map(ClassB::getSomeString)
                          .collect(toList()));