W pewnym momencie w moim kodzie utworzyłem Set<Map.Entry<K, V>>
z mapy. Teraz chcę odtworzyć ten sam formularz mapy, więc chcę przekonwertować HashSet<Map.Entry<K, V>>
z powrotem na HashMap<K, V>
. Czy Java ma natywne wezwanie do robienia tego, czy też muszę zapętlić ustawione elementy i ręcznie zbudować mapę?Konwertuj zestaw <Map.Entry <K, V>> na HashMap <K, V>
Odpowiedz
Nie ma wbudowany interfejs API w Java dla bezpośredniej konwersji pomiędzy HashSet
i HashMap
, trzeba wykonać iterację zestaw i korzystania Entry
wypełnić mapie.
jedno podejście:
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());
}
Choć Jaki jest cel tutaj, jeśli nie żadnych zmian w Set
że odbije się także w Map
jako zbioru zwróconego przez Map.entrySet
jest tworzenie kopii zapasowych przez Map
. Zobacz javadoc
poniżej:
Ustaw < Wstęp < Integer, String >> java.util.Map.entrySet()
zwraca zestaw widok mapowania zawartych w tej mapie. Zbiór jest wspierany przez mapę, więc zmiany na mapie są odzwierciedlone w zestawie i na odwrót. Jeśli mapa zostanie zmodyfikowana, gdy trwa iteracja nad zestawem, to w toku (z wyjątkiem operacji usuwania iteratora lub poprzez operację setValue na pozycji mapy zwróconej przez iterator ) wyniki iteracji są niezdefiniowane. Zestaw obsługuje usuwanie elementu , który usuwa odpowiednie mapowanie z mapy, za pomocą operacji Iterator.remove, Set.remove, removeAll, retainAll i clear . Nie obsługuje operacji dodawania ani dodawania.
Dość krótkie rozwiązanie Java 8. Może poradzić sobie z duplikatami kluczy.
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));
Edit: dzięki shmosel kto zasługuje na więcej punktów niż ja w tym
Nie. Twój BiConsumer nie łączy map. – Joe
W powyższym kodzie metoda akceptacji BiConsumer nigdy nie jest wywoływana. Wolałbym użyć wartości NULL, ale metoda zbierania głupio wyrzuca NPE w tym przypadku. – mikeyreilly
@mikeyreilly, [dokumentacja] (https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#collect-java.util.function.Supplier-java.util .function.BiConsumer-java.util.function.BiConsumer-) nie mówi wprost, że kombinator nigdy nie jest wywoływany dla strumienia sekwencyjnego. W ten sposób po prostu naruszysz umowę z tą metodą. –
w Java 8 z prawidłowym sumator
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;}););
Prostsze-8 Java rozwiązanie obejmujące Collectors.toMap
:
Map<Integer, String> mapFromSet = set.stream()
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
An IllegalStateException
zostanie wyrzucony, jeśli d pojawia się klucz uplicate.
co aboug NPEs, jeśli dowolna wartość jest null? –
Jak guawa 19 można użyć ImmutableMap.copyOf(Iterable<Map.Entry<K,V>>)
Jako Java 9, mamy Map.ofEntries. Biorą one jednak tylko wpisy jako tablice, więc musisz je najpierw przekonwertować z toArray()
i wyrzucić informacje o typie.
@SuppressWarnings("unchecked")
(Map.Entry<K, V>[] array = entrySet.toArray((Map.Entry<K, V>[])new Map.Entry<?, ?>[entrySet.size()]);
Map<K, V> map = Map.ofEntries(array);
Apache Commons ma podobne metody.Fotografia Langa 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;
Commons Collections' MapUtils.putAll:
Map<K, V> map = MapUtils.putAll(new HashMap<K, V>(), entrySet.toArray());
Skąd stworzony '' Map' Set' z logiką, używając klucza lub wartości lub niestandardowy? poza tym nie ma "natywnej" metody dla 'HashSet' na' HashMap'. Musisz przejść do iteracji i użyć jakiejś logiki podczas wstawiania do 'HashMap' sposobu wyboru klucza i wartości. – harsh
@Paul dziękuję teraz pytanie brzmi jednoznacznie – harsh
Nie sądzę, że 'Map.Entry' ma być używany w ten sposób. Czy implementacja używana na przykład przez 'HashMap' nadpisuje' hashCode' i 'equals'? –