我有一个HashMap,我想得到一个新的HashMap,它只包含第一个HashMap中的元素,其中K属于一个特定的List.
我可以查看所有的键并填充一个新的HashMap,但我想知道是否有更有效的方法来做到这一点?
谢谢
T.G*_*lle 19
使用Java8流,有一个功能(优雅)的解决方案.如果keys是要保留的键列表并且map是源Map.
keys.stream()
.filter(map::containsKey)
.collect(Collectors.toMap(Function.identity(), map::get));
Run Code Online (Sandbox Code Playgroud)
完整的例子:
List<Integer> keys = new ArrayList<>();
keys.add(2);
keys.add(3);
keys.add(42); // this key is not in the map
Map<Integer, String> map = new HashMap<>();
map.put(1, "foo");
map.put(2, "bar");
map.put(3, "fizz");
map.put(4, "buz");
Map<Integer, String> res = keys.stream()
.filter(map::containsKey)
.collect(Collectors.toMap(Function.identity(), map::get));
System.out.println(res.toString());
Run Code Online (Sandbox Code Playgroud)
打印: {2=bar, 3=fizz}
编辑filter为地图中缺少的键添加一个
T.G*_*lle 10
是的,有一个解决方案:
Map<K,V> myMap = ...;
List<K> keysToRetain = ...;
myMap.keySet().retainAll(keysToRetain);
Run Code Online (Sandbox Code Playgroud)
上的retainAll操作Set更新底层地图。请参阅Java 文档。
编辑
请注意此解决方案修改Map.
如果您有 Map m1 和 List 键,请尝试以下操作
Map m2 = new HashMap(m1);
m2.keySet().retainAll(keys);
Run Code Online (Sandbox Code Playgroud)
在番石榴的帮助下。
假设您有一个地图Map<String, String>并希望使用List<String>列表中的值进行子映射。
Map<String, String> map = new HashMap<>();
map.put("1", "1");
map.put("2", "2");
map.put("3", "4");
final List<String> list = Arrays.asList("2", "4");
Map<String, String> subMap = Maps.filterValues(
map, Predicates.in(list));
Run Code Online (Sandbox Code Playgroud)
更新/注意:正如评论中提到的@assylias,使用contains(). 因此,如果您的列表很大,这可能会对性能产生巨大影响。
另一方面HashSet.contains()是恒定时间 O(1),所以如果有可能使用 Set 而不是 List,这可能是一个不错的方法(请注意,将 List 转换为 Set 无论如何都会花费 O(n),所以最好不要转变 :))
如果您的键有顺序,则可以使用 TreeMap。
看着TreeMap.subMap()
但它不允许您使用列表来执行此操作。