根据其键的子集过滤地图的元素,而无需遍历整个事物

Posted

技术标签:

【中文标题】根据其键的子集过滤地图的元素,而无需遍历整个事物【英文标题】:Filter the elements of a map based on a subset of its keys without iterating through the entire thing 【发布时间】:2011-10-08 00:32:46 【问题描述】:

我有一个Map<String, ArrayList> 和一个Set<String>。有没有办法将映射的键与字符串集“相交”,以便只保留具有给定键的对,而不遍历整个映射?我主要关心的是性能和在可以更优雅地完成的事情上重新发明***。

【问题讨论】:

【参考方案1】:

只要做:

map.keySet().retainAll(set);

根据javadoc,密钥集的更改会反映在映射中。

...集合由地图支持,因此对地图的更改会反映在集合中,反之亦然。 ...

这是一个演示:

Map<String, String> map = new HashMap<String, String>();
map.put("1", "one");
map.put("2", "two");
map.put("3", "three");

Set<String> set = new HashSet<String>();
set.add("1");
set.add("3");

map.keySet().retainAll(set);

System.out.println(map); // 3=three, 1=one

【讨论】:

哇。从来不知道KeySet 支持retainAll。太有用了。 使用自 1.1 以来的集合 - 也不知道这一点。 非常有用。 values() 也支持这一点。【参考方案2】:

详细阐述 BalusC 的出色答案,values() 也支持 retainAll():

Map<String, String> map = new HashMap<String, String>();
map.put("1", "one");
map.put("2", "two");
map.put("3", "three");

Set<String> set = new HashSet<String>();
set.add("one");
set.add("two");

map.values().retainAll(set);

System.out.println(map);   // prints 1=one, 2=two

retailAll 也会保留重复值,正如您所期望的:

Map<String, String> map = new HashMap<String, String>();
map.put("1", "one");
map.put("2", "two");
map.put("3", "three");
map.put("4", "two");

Set<String> set = new HashSet<String>();
set.add("one");
set.add("two");

map.values().retainAll(set);

System.out.println(map);  // prints 1=one, 2=two, 4=two

【讨论】:

以上是关于根据其键的子集过滤地图的元素,而无需遍历整个事物的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Ajax 加载过滤后的数据,而无需在 laravel 中重新加载整个页面

LeetCode 腾讯精选50题--子集

返回唯一值并避免遍历未过滤的范围

根据对象中键的名称过滤对象数组[重复]

78子集

jq 过滤内部数组元素但返回整个 JSON