Есть ли разумный способ получить все значения с карты с некоторыми ключами?
Мне нужен такой метод:
public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys)
или уже является способом guava?
Есть ли разумный способ получить все значения с карты с некоторыми ключами?
Мне нужен такой метод:
public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys)
или уже является способом guava?
Это зависит от того, как вы хотите, чтобы этот метод работал. Например, если элементы в 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
для кода с использованием возвращенной коллекции в какой-то момент.
Я согласен с ответом скаффмана, просто не с его заключением (я думаю, что это лучше, чем ручная итерация).
Здесь написано:
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();
}
Вы могли бы, я полагаю, использовать Guava Maps.filteredKeys()
, передавая в Predicate
, который соответствует вашим желаемым клавишам, но это не лучше, чем ручная итерация.
Использование guava:
Collections2.transform(keys, Functions.forMap(map));