是否有一种聪明的方法可以在给定一些键的情况下从地图中获取所有值?
我想要一个像这样的方法:
public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys)
或已经是一种番石榴方式?
答案 0 :(得分:18)
这取决于您希望方法如何工作。例如,keys
中不在map
A)中的元素应该被忽略,还是 B)表示为{{ 1}}在返回的值集合中还是 C)是错误的?还要考虑您是想要实时视图还是包含值的单独集合。
对于 A ,我的偏好是:
null
这会将结果限制为实际位于地图中的键的值,并且即使地图比您想要的键组大得多,也应该相对有效。当然,您可能希望将结果复制到另一个集合中,具体取决于您要对其执行的操作。
对于 B ,您使用@Michael Brewer-Davis的解决方案,Collection<V> values = Collections2.transform(
Collections2.filter(keys, Predicates.in(map.keySet()),
Functions.forMap(map));
除外。
对于 C ,您首先要检查Functions.forMap(map, null)
并在map.keySet().containsAll(keys)
时抛出错误,然后使用@Michael Brewer-Davis的解决方案......但是意识到除非您随后将结果复制到另一个集合中,否则从false
中删除条目可能会导致map
代码在某个时刻使用返回的集合。
答案 1 :(得分:13)
我同意skaffman的回答,而不是他的结论(我认为这比手动迭代更好)。
这里拼写出来:
public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys) {
return Maps.filterKeys(map, Predicates.in(keys)).values();
}
此外,这是一个非番石榴版本:
public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys) {
Map<K, V> newMap = new HashMap<K, V>(map);
newMap.keySet().retainAll(keys);
return newMap.values();
}
答案 2 :(得分:3)
你可以,我想使用Guava的Maps.filteredKeys()
,传入一个匹配你想要的键的Predicate
,但它并不比手动迭代更好。
答案 3 :(得分:3)
使用番石榴:
Collections2.transform(keys, Functions.forMap(map));
答案 4 :(得分:0)
Java8流:
keys.stream().map( map::get ).collection( Collection.toList() );
或者如果您担心丢失键:
keys.stream().map( k -> map.getOrDefault( k, null ) ).collection( Collection.toList() );
或者如果您的地图是线程安全的并且可能性很大:
keys.parallelStream().map( map::get ).collection( Collection.toList() );