从Map中获取Java/Guava中的一些键的所有值?

Flo*_*ver 12 java collections maps guava

是否有一种聪明的方法可以从一个地图中获取所有值?

我想要一个像这样的方法:

public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys)
Run Code Online (Sandbox Code Playgroud)

或者已经是番石榴的方式?

Col*_*inD 19

这取决于您希望方法如何工作.例如,应元件keys不在map A)只是被忽略还是应该B)被表示为null在返回的值集合或应该C)是一个错误?还要考虑您是要实时视图还是包含值的单独集合.

对于A,我的偏好是:

Collection<V> values = Collections2.transform(
    Collections2.filter(keys, Predicates.in(map.keySet()),
    Functions.forMap(map));
Run Code Online (Sandbox Code Playgroud)

这会将结果限制为实际位于地图中的键的值,并且即使地图比您想要的键组大得多,也应该相对有效.当然,您可能希望将结果复制到另一个集合中,具体取决于您要对其执行的操作.

对于B,你会使用@Michael Brewer-Davis的解决方案,除了Functions.forMap(map, null).

对于C,你首先要检查map.keySet().containsAll(keys)并抛出一个错误false,然后使用@Michael Brewer-Davis的解决方案......但要注意,除非你将结果复制到另一个集合中,否则删除一个条目map可能导致IllegalArgumentException对于在某些时候使用返回的集合的代码.


Sea*_*oyd 13

我同意skaffman的回答,而不是他的结论(我认为这比手动迭代更好).

这里拼写出来:

public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys) {
    return Maps.filterKeys(map, Predicates.in(keys)).values();
}
Run Code Online (Sandbox Code Playgroud)

此外,这是一个非番石榴版本:

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();
}
Run Code Online (Sandbox Code Playgroud)

  • 我使用`filterKeys`的问题是:A)它需要迭代遍历`map`的每个条目,即使`keys`要小得多(反过来看起来像这样的方法不太可能),以及B)如果`keys`集合没有快速的`contains`实现,为地图中的每个条目调用一次将增加调用的复杂性顺序.我给的代码没有这些问题.对于非Guava版本,我认为循环会更好......你的版本需要在内存中保留地图的整个副本,即使结果为空. (2认同)