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

2022-09-03 17:25:12

有没有一种聪明的方法可以从给定一些键的地图中获取所有值?

我想要一个这样的方法:

public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys)

还是已经是番石榴的方式?


答案 1

这取决于您希望该方法的工作方式。例如,A中不在其中的元素应该被忽略,还是应该将它们B)表示为在返回值集合中,或者C)应该是一个错误?还要考虑是需要实时视图还是包含值的单独集合。keysmapnull

对于A,我的偏好是:

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

这会将结果限制为实际位于映射中的键的值,并且即使映射比所需的键集大得多,也应该相对高效。当然,您可能希望将该结果复制到另一个集合中,具体取决于您要对其进行处理。

对于 B,您将使用@Michael Brewer-Davis 的解决方案,但 .Functions.forMap(map, null)

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


答案 2

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

这里拼写出来:

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

另外,这是一个非番石榴版本(Java 8或更高版本):

public static <K, V> Collection<V> getAll(Map<K, V> map, Set<K> keys) {
    return map.entrySet()
            .stream()
            .filter(e -> keys.contains(e.getKey()))
            .map(Map.Entry::getValue)
            .collect(Collectors.toList());
}