Map<Integer, String> map = new HashMap<>();
map.put(1, "string 1");
map.put(2, "string 2");
map.put(3, "string 3");
A oto jak uzyskać wartości według klucza:
String string1 = map.get(1);
String string2 = map.get(2);
String string3 = map.get(3);
Jeśli wszystko powyższe jest jasne, przejdźmy do naszych odpowiedzi na popularne pytania!
0. Jak iterować po wszystkich wartościach mapy
Iteracja po wartościach to najczęstsza operacja wykonywana na mapach. Wszystkie pary klucz-wartość przechowywane są w wewnętrznym interfejsie Map.Entry i aby je uzyskać należy wywołać funkcjęentrySet()
. Zwraca zestaw par, które można zapętlić:
for(Map.Entry<Integer, String> entry: map.entrySet()) {
// get key
Integer key = entry.getKey();
// get value
String value = entry.getValue();
}
Или используя итератор:
Iterator<Map.Entry<Integer, String>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry<Integer, String> entry = itr.next();
// get key
Integer key = entry.getKey();
// get value
String value = entry.getValue();
}
1. Jak przekonwertować mapę na listę
Interfejs Map posiada 3 metody zwracające listę elementów:- keySet() - zwraca zestaw kluczy;
- wartości() - zwraca kolekcję wartości;
- EntrySet() - zwraca zestaw zestawów klucz-wartość.
ArrayList
, zauważysz, że istnieje konstruktor z argumentem typu Collection. Ponieważ Set jest potomkiem Collection, wyniki wszystkich powyższych metod można przekazać do konstruktora klasy ArrayList
. Stworzymy więc nowe listy i wypełnimy je wartościami z Map
:
// key list
List<Integer> keyList = new ArrayList<>(map.keySet());
// value list
List<String> valueList = new ArrayList<>(map.values());
// key-value list
List<Map.Entry<Integer, String>> entryList = new ArrayList<>(map.entrySet());
2. Jak sortować klucze mapy
Sortowanie map jest również dość powszechną operacją w programowaniu. Możesz to zrobić na kilka sposobów:-
Umieść Map.Entry na liście i posortuj ją za pomocą Comparatora .
W komparatorze będziemy porównywać tylko klucze par:
List
> list = new ArrayList(map.entrySet()); Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() { @Override public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) { return o1.getKey() - o2.getKey(); } }); Jeśli rozumiesz lambdy, ten wpis można znacznie skrócić:
Collections.sort(list, Comparator.comparingInt(Map.Entry::getKey));
-
Użyj
SortedMap
, a dokładniej jego implementacjęTreeMap
, która w swoim konstruktorze przyjmuje Comparator. Ten komparator zostanie zastosowany do kluczy mapy, więc klucze muszą być klasami implementującymi interfejsComparable
:SortedMap<Integer, String> sortedMap = new TreeMap<>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } });
I oczywiście wszystko można przepisać za pomocą lambd:
SortedMap<Integer, String> sortedMap = new TreeMap<>(Comparator.comparingInt(o -> o));
W przeciwieństwie do pierwszej metody, korzystając z SortedMap, dane zawsze będziemy przechowywać w formie posortowanej.
3. Jak sortować wartości mapy
Tutaj należy zastosować podejście podobne do pierwszego dla kluczy - uzyskaj listę wartości i posortuj je na liście:List <Map.Entry<Integer, String>> valuesList = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
@Override
public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
A lambda tego wygląda następująco:
Collections.sort(list, Comparator.comparing(Map.Entry::getValue));
4. Jaka jest różnica pomiędzy HashMap, TreeMap i Hashtable
Jak wspomniano wcześniej, istnieją 3 główne implementacje interfejsu Map. Każdy z nich ma swoją własną charakterystykę:-
Kolejność elementów.
HashMap
iHashtable
nie gwarantujemy, że elementy będą przechowywane w kolejności, w jakiej zostały dodane. Ponadto nie dają gwarancji, że kolejność elementów nie ulegnie zmianie w czasie. Gwarantuje to z koleiTreeMap
przechowywanie elementów w kolejności ich dodawania lub zgodnie z danym komparatorem. -
Prawidłowe wartości.
HashMap
pozwala mieć klucz i wartość null,HashTable
nie. TreeMap może używać wartości null tylko jeśli komparator na to pozwala. Bez użycia komparatora (poprzez przechowywanie par w kolejności, w jakiej zostały dodane), wartość null jest niedozwolona. -
Synchronizacja. Tylko
HashTable
zsynchronizowane, reszta nie. Jeśli dostęp do mapy nie będzie możliwy dla różnych wątków, zaleca się użycie HashMap zamiast HashTable.
HashMapa | HashTable | Mapa Drzewa | |
---|---|---|---|
Kolejność elementów | NIE | NIE | Tak |
null jako wartość | Tak | NIE | Nie bardzo |
Bezpieczeństwo nici | NIE | Tak | NIE |
Złożoność algorytmiczna wyszukiwania elementów | O(1) | O(1) | O(log n) |
Struktura danych pod maską | tablica mieszająca | tablica mieszająca | czerwono-czarne drzewo |
5. Jak stworzyć mapę dwukierunkową
Czasami konieczne staje się zastosowanie struktury danych, w której zarówno klucze, jak i wartości będą unikalne, czyli mapa będzie zawierać pary klucz-klucz. Ta struktura danych umożliwia utworzenie na mapie „odwróconego widoku/wyszukiwania”. Oznacza to, że klucz możemy znaleźć po jego wartości.Ta struktura danych nazywa się mapą dwukierunkową, która niestety nie jest obsługiwana przez JDK. Ale na szczęście jego implementację można znaleźć w bibliotekach Apache Common Collections lub Guava. Tam nazywa się to odpowiednio BidiMap i BiMap. Implementacje te nakładają ograniczenia na unikalność kluczy i wartości. Tworzy to relację jeden do jednego.6. Jak stworzyć pustą mapę
Istnieją dwa sposoby utworzenia pustej mapy:-
Normalna inicjalizacja obiektu:
Map<Integer, String> emptyMap = new HashMap<>();
-
Tworzenie niezmiennej pustej mapy:
Map<Integer, String> emptyMap = Collections.emptyMap();
UnsupportedOperationException
wyjątek. W tym artykule przyjrzeliśmy się najczęstszym pytaniom, jakie możesz mieć podczas korzystania z interfejsu Mapy.
Co jeszcze warto przeczytać: |
---|
GO TO FULL VERSION