2010-12-14 10 views
12

już wiem jak zrobić to w przykry sposób i got it pracy - iteracji po wpisach i zamiana „ręcznie”. Ale zastanawiam się, czy tak jak wiele zadań, ten można rozwiązać w bardziej elegancki sposób.Jak zamienić klucze i wartości w Mapie elegancko

Czytałem this post niestety nie posiadają eleganckie rozwiązania. Nie mam też możliwości użycia żadnych wymyślnych Guava BiMaps ani niczego poza jdk (stos projektu jest już zdefiniowany).

mogę założyć, że moja mapa jest bijective, btw :)

+3

Dodanie dodatkowej biblioteki narzędzie nie jest tak naprawdę zmianę projektu „stos” w taki sposób, że (powiedzmy) zmiana, która ramy UI używasz będzie.Zachęcam was do ponownego rozważenia swojego sprzeciwu wobec używania Guawy, jeśli wszystko jest możliwe *. –

+0

Wszystko czego potrzebujesz to pojedyncza pętla z pojedynczą linią jest prosta i elegancka. MOIM ZDANIEM. Java nie jest językiem funkcjonalnym. –

+0

dziękuję wszystkim, przy tych wszystkich nakładających się i zwięzłych odpowiedziach naprawdę trudno jest wybrać, który z nich przyjąć. Chyba pójdę z Aaronem Digulla za zapewnienie obejścia. – kostja

Odpowiedz

8

Standardowy czas pracy API/Java nie oferuje dwukierunkową mapę, więc jedynym rozwiązaniem jest iteracyjne nad wszystkie wpisy i zamienić je ręcznie.

Co można zrobić, to utworzyć klasę opakowania, która zawiera dwie mapy i która ma wewnętrzną wewnętrzną wersję, dzięki czemu można szybko uzyskać dwa widoki danych.

[EDYCJA] Ponadto, dzięki otwartemu źródłu, nie musisz dołączać biblioteki innej firmy, możesz po prostu skopiować potrzebne klasy do swojego projektu.

3

Mapy nie są jak list, który można odwrócić przez zamianę głowy z ogonem.

Obiekty mapy mają pozycję komputerowej, a przy użyciu wartości jako klucz i klucz jako wartość będzie requiere aby ponownie obliczyć miejsce przechowywania, essentialy budowę inną mapę. Nie ma eleganckiej drogi.

Istnieją jednak dwukierunkowe mapy. Te mogą odpowiadać twoim potrzebom. Ponownie rozważałbym korzystanie z bibliotek innych firm.

2

Istnieją pewne zadania, które mogą być uproszczone do pewnego punktu, a nie więcej. To może być jedna z nich!

Jeśli chcesz wykonać zadanie za pomocą kolekcji Java apis tylko wtedy brutalna siła jest drogą do zrobienia - będzie szybka (chyba że kolekcja jest ogromna) i będzie oczywistym kawałkiem kodu.

20

Jeśli nie masz wyboru, aby użyć biblioteki strony trzeciej, nie uważam następujący kod tak brzydki (chociaż niektóre języki skryptowe mają eleganckie sposoby robienia IT):

//map must be a bijection in order for this to work properly 
public static <K,V> HashMap<V,K> reverse(Map<K,V> map) { 
    HashMap<V,K> rev = new HashMap<V, K>(); 
    for(Map.Entry<K,V> entry : map.entrySet()) 
     rev.put(entry.getValue(), entry.getKey()); 
    return rev; 
} 
+0

dziękuję, ten przypomina mi mój własny kod :) – kostja

14
Map<String, Integer> map = new HashMap<>(); 
Map<Integer, String> swapped = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); 
+0

niesamowite rozwiązanie. – chandresh

0

Jako podpowiedź odpowiedzieć https://stackoverflow.com/a/42091477/8594421

działa to tylko, jeśli mapa nie jest HashMap i nie zawiera zduplikowanych wartości.

Map<String,String> newMap = oldMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); 

zgłasza wyjątek

java.lang.IllegalStateException: duplikatów kluczy

jeśli istnieją wartości więcej niż jeden raz.

Rozwiązanie:

HashMap<String,String> newMap = new HashMap<>(); 

for(Map.Entry<String,String> entry : oldMap.entrySet()) 
     newMap.put(entry.getValue(), entry.getKey()); 

// Add inverse to old one 
oldMap.putAll(newMap); 
Powiązane problemy