Zgadzam się z rzeczą LinkedHashMap. Po prostu umieszczam moje odkrycia i doświadczenie, gdy miałem problem, gdy próbowałem sortować HashMap według kluczy.
Mój kod do tworzenia HashMap:
HashMap<Integer, String> map;
@Before
public void initData() {
map = new HashMap<>();
map.put(55, "John");
map.put(22, "Apple");
map.put(66, "Earl");
map.put(77, "Pearl");
map.put(12, "George");
map.put(6, "Rocky");
}
Mam funkcję showMap, która wyświetla wpisy mapy:
public void showMap (Map<Integer, String> map1) {
for (Map.Entry<Integer, String> entry: map1.entrySet()) {
System.out.println("[Key: "+entry.getKey()+ " , "+"Value: "+entry.getValue() +"] ");
}
}
Teraz, kiedy drukuję mapę przed sortowaniem, wypisuje następującą sekwencję:
Map before sorting :
[Key: 66 , Value: Earl]
[Key: 22 , Value: Apple]
[Key: 6 , Value: Rocky]
[Key: 55 , Value: John]
[Key: 12 , Value: George]
[Key: 77 , Value: Pearl]
Która jest zasadniczo inna niż kolejność, w której zostały umieszczone klucze mapy.
Teraz, kiedy posortuję go za pomocą kluczy mapy:
List<Map.Entry<Integer, String>> entries = new ArrayList<>(map.entrySet());
Collections.sort(entries, new Comparator<Entry<Integer, String>>() {
@Override
public int compare(Entry<Integer, String> o1, Entry<Integer, String> o2) {
return o1.getKey().compareTo(o2.getKey());
}
});
HashMap<Integer, String> sortedMap = new LinkedHashMap<>();
for (Map.Entry<Integer, String> entry : entries) {
System.out.println("Putting key:"+entry.getKey());
sortedMap.put(entry.getKey(), entry.getValue());
}
System.out.println("Map after sorting:");
showMap(sortedMap);
wyjście to:
Sorting by keys :
Putting key:6
Putting key:12
Putting key:22
Putting key:55
Putting key:66
Putting key:77
Map after sorting:
[Key: 66 , Value: Earl]
[Key: 6 , Value: Rocky]
[Key: 22 , Value: Apple]
[Key: 55 , Value: John]
[Key: 12 , Value: George]
[Key: 77 , Value: Pearl]
Możesz zobaczyć różnicę w kolejności kluczy. Posortowana kolejność kluczy jest w porządku, ale klucz skopiowanej mapy jest ponownie w tej samej kolejności, co wcześniejsza mapa. Nie wiem, czy można to powiedzieć, ale dla dwóch hashmap z tymi samymi kluczami kolejność kluczy jest taka sama. Oznacza to, że kolejność kluczy nie jest gwarantowana, ale może być taka sama dla dwóch map z tymi samymi kluczami ze względu na nieodłączną naturę algorytmu wstawiania kluczy, jeśli implementacja HashMap tej wersji maszyny JVM.
Teraz, kiedy używam LinkedHashMap do kopiowania posortowanych wpisów do HashMap, otrzymuję pożądany wynik (co było naturalne, ale nie o to chodzi. Chodzi o kolejność kluczy w HashMap)
HashMap<Integer, String> sortedMap = new LinkedHashMap<>();
for (Map.Entry<Integer, String> entry : entries) {
System.out.println("Putting key:"+entry.getKey());
sortedMap.put(entry.getKey(), entry.getValue());
}
System.out.println("Map after sorting:");
showMap(sortedMap);
Wynik:
Sorting by keys :
Putting key:6
Putting key:12
Putting key:22
Putting key:55
Putting key:66
Putting key:77
Map after sorting:
[Key: 6 , Value: Rocky]
[Key: 12 , Value: George]
[Key: 22 , Value: Apple]
[Key: 55 , Value: John]
[Key: 66 , Value: Earl]
[Key: 77 , Value: Pearl]