В какой-то момент в моем коде я создал Set<Map.Entry<K, V>>
с карты. Теперь я хочу воссоздать одну и ту же форму карты, поэтому я хочу преобразовать HashSet<Map.Entry<K, V>>
обратно в HashMap<K, V>
. У Java есть собственный вызов для этого, или мне нужно перебрать установленные элементы и построить карту вручную?
Преобразовать Set <Map.Entry <K, V >> в HashMap <K, V>
Ответ 1
В Java нет встроенного API для прямого преобразования между HashSet
и HashMap
, вам нужно выполнить итерацию по набору и используя Entry
заполнить карту.
один подход:
Map<Integer, String> map = new HashMap<Integer, String>();
//fill in map
Set<Entry<Integer, String>> set = map.entrySet();
Map<Integer, String> mapFromSet = new HashMap<Integer, String>();
for(Entry<Integer, String> entry : set)
{
mapFromSet.put(entry.getKey(), entry.getValue());
}
Хотя здесь и есть цель, если вы внесете какие-либо изменения в Set
, которые также будут отображаться в Map
, поскольку set, возвращаемый Map.entrySet
, является резервной копией Map
. См. Ниже javadoc
:
Set < Entry < Integer, String → java.util.Map.entrySet()
Возвращает представление Set из отображений, содержащихся в этой карте. Множество поддерживаемые картой, поэтому изменения в карте отражаются в наборе, и наоборот. Если карта изменена, а итерация по множеству (за исключением операции удаления собственного итератора или через операцию setValue на запись карты, возвращаемую итератор), результаты итерации undefined. Набор поддерживает удаление элемента, которое удаляет соответствующее отображение с карты, через Iterator.remove, Set.remove, removeAll, убрать все и очистить операции. Он не поддерживает операции add или addAll.
Ответ 2
Упрощенное решение Java-8 с участием Collectors.toMap
:
Map<Integer, String> mapFromSet = set.stream()
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
А IllegalStateException
будет вызываться, если встречается дублирующийся ключ.
Ответ 3
Довольно короткое решение Java 8. Может справиться с дублирующимися ключами.
Map<Integer, String> map = new HashMap<>();
//fill in map
Set<Map.Entry<Integer, String>> set = map.entrySet();
Map<Integer, String> mapFromSet = set.stream().collect(Collectors.toMap(Entry::getKey,
Entry::getValue,
(a,b)->b));
Изменить: благодаря shmosel, который заслуживает большего доверия, чем я для этого
Ответ 4
Начиная с Guava 19 вы можете использовать ImmutableMap.copyOf(Iterable<Map.Entry<K,V>>)
Ответ 5
Это некоторые утилиты toMap
в общих библиотеках, но, к сожалению, ни одна из них не поддерживает Set
напрямую, поэтому вам нужно сначала выполнить Set#toArray()
. (Я оставил Guava для ответа Нейла, который, возможно, является лучшим)
Commons Lang ArrayUtils.toMap
Map<Object, Object> map = ArrayUtils.toMap(entrySet.toArray());
// to recover the type...
@SuppressWarnings("unchecked")
Map<K, V> typedMap = (Map<K, V>)(Map<?, ?>)map;
MapUtils.putAll Коллекций общин
Map<K, V> map = MapUtils.putAll(new HashMap<K, V>(), entrySet.toArray());
Java 9 Map.ofEntries
// convert to array and recover the type...
@SuppressWarnings("unchecked")
Map<K, V> map = Map.ofEntries(entrySet.toArray(new Map.Entry[0]));
// You need to copy again if you want a mutable one
Map<K, V> hashmap = new HashMap<>(map);
Ответ 6
В Java 8 с правильным объединителем
Map<Integer, String> map = new HashMap<>();
//fill in map
Set<Map.Entry<Integer, String>> set = map.entrySet();
Map<Integer, String> mapFromSet =set.stream().collect(HashMap::new,(t, u) -> t.put(u.getKey(), u.getValue()),
(Map mapToReturn, Map otherMap) ->
{
otherMap.entrySet().forEach((Map.Entry entry) -> {
mapToReturn.put(entry.getKey(),entry.getValue());
});
return mapToReturn;}););