Подтвердить что ты не робот

Преобразовать Set <Map.Entry <K, V >> в HashMap <K, V>

В какой-то момент в моем коде я создал Set<Map.Entry<K, V>> с карты. Теперь я хочу воссоздать одну и ту же форму карты, поэтому я хочу преобразовать HashSet<Map.Entry<K, V>> обратно в HashMap<K, V>. У Java есть собственный вызов для этого, или мне нужно перебрать установленные элементы и построить карту вручную?

4b9b3361

Ответ 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, который заслуживает большего доверия, чем я для этого

Ответ 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;}););