如何比较地图与列表

时间:2017-01-09 18:42:28

标签: java collections hashmap contains

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

我有一个HashMap,如下所示:

Map<String, ClassA> myMap;

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

List<ClassB> myList;

ClassB如下所示:

   public class ClassB{

    //many things

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

someString是键字符串myMap

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

任何算法?模式甚至是例子?

谢谢

3 个答案:

答案 0 :(得分:5)

为了做到这一点,你必须至少迭代List<ClassB> myList一次,但是你可以完全用一次迭代来完成它,这使得它在理算上是理想的。

创建一个新的地图,并为列表中的每个元素检查它是否在myMap中,如果它在那里 - 将其添加到您创建的新地图中。完成迭代后,只需指定:myMap = newMap;即可完成。

注意:这对于最少的步骤是理想的,但 使用的内存比“就地”算法更多。

答案 1 :(得分:2)

使用java 8 stream 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,因此这将占用比当前解决方案更少的内存。

答案 2 :(得分:2)

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

接下来,您希望保留不在List<ClassB>中的元素,而是保留在从ClassB的每个实例派生的字符串列表中。您可以使用流来完成此操作。

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