Получить все значения из карты для некоторых ключей в Java/Guava?

Есть ли разумный способ получить все значения с карты с некоторыми ключами?

Мне нужен такой метод:

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

или уже является способом guava?

Ответ 1

Это зависит от того, как вы хотите, чтобы этот метод работал. Например, если элементы в keys, которые не находятся в map A), просто игнорируются или должны быть B) представлены как null в возвращаемом значения или должна быть ошибка C)? Также рассмотрите, хотите ли вы просмотр в реальном времени или отдельную коллекцию, содержащую значения.

Для 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 сначала нужно проверить, что map.keySet().containsAll(keys) и выбросить ошибку, если false, а затем использовать решение @Michael Brewer-Davis... но имейте в виду, что если вы затем скопировал результат в другую коллекцию, удаление записи из map может привести к IllegalArgumentException для кода с использованием возвращенной коллекции в какой-то момент.

Ответ 2

Я согласен с ответом скаффмана, просто не с его заключением (я думаю, что это лучше, чем ручная итерация).

Здесь написано:

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

Кроме того, здесь версия, отличная от Guava:

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();
}

Ответ 3

Вы могли бы, я полагаю, использовать Guava Maps.filteredKeys(), передавая в Predicate, который соответствует вашим желаемым клавишам, но это не лучше, чем ручная итерация.

Ответ 4

Использование guava: Collections2.transform(keys, Functions.forMap(map));