Sortiere eine HashMap in Java

Sortieren Sie eine HashMap in Java

1. Einführung

In diesem kurzen Tutorial lernen wir, wie mansort a HashMap in Java macht.

Insbesondere werden wir die Einträge vonHashMapnach ihrem Schlüssel oder Wert sortieren, indem wir Folgendes verwenden:

  • Baumkarte

  • ArrayList undCollections.sort()

  • TreeSet

  • Verwenden derStream API, und schließlich

  • Verwenden derGuava -Slibrary

2. Verwenden vonTreeMap

Wie wir wissen,keys in TreeMap are sorted using their natural order. Dies ist eine gute Lösung, wenn Sie die Schlüssel-Wert-Paare nach ihrem Schlüssel sortieren möchten. Die Idee ist also, alle Daten von unserenHashMap in dieTreeMap zu verschieben.

Definieren wir zunächst einHashMap und initialisieren es mit einigen Daten:

Map map = new HashMap<>();

Employee employee1 = new Employee(1L, "Mher");
map.put(employee1.getName(), employee1);
Employee employee2 = new Employee(22L, "Annie");
map.put(employee2.getName(), employee2);
Employee employee3 = new Employee(8L, "John");
map.put(employee3.getName(), employee3);
Employee employee4 = new Employee(2L, "George");
map.put(employee4.getName(), employee4);

Für die KlasseEmployee giltnote that we’ve implemented Comparable:

public class Employee implements Comparable {

    private Long id;
    private String name;

    // constructor, getters, setters

    // override equals and hashCode
    @Override
    public int compareTo(Employee employee) {
        return (int)(this.id - employee.getId());
    }
}

Als nächstes speichern wir die Einträge inTreeMap by mit seinem Konstruktor:

TreeMap sorted = new TreeMap<>(map);

Oder die MethodeputAllzum Kopieren der Daten:

TreeMap sorted = new TreeMap<>();
sorted.putAll(map);

Und das ist es! Um sicherzustellen, dass unsere Karteneinträge nach Schlüsseln sortiert sind, drucken wir sie aus:

Annie=Employee{id=22, name='Annie'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Mher=Employee{id=1, name='Mher'}

Wie wir sehen, sind die Schlüssel in natürlicher Reihenfolge sortiert.

3. Verwenden vonArrayList

Natürlich können wir die Einträge der Karte mit Hilfe vonArrayList sortieren. Der Hauptunterschied zur vorherigen Methode besteht darin, dasswe don’t maintain the Map interface here.

3.1. Nach Schlüssel sortieren

Laden wir den Schlüsselsatz inArrayList:

List employeeByKey = new ArrayList<>(map.keySet());
Collections.sort(employeeByKey);

Und die Ausgabe ist:

[Annie, George, John, Mher]

3.2. Nach Wert sortieren

Was ist nun, wenn wir unsere Kartenwerte nach dem Feldiddes ObjektsEmployeeortieren möchten? Auch dafür können wir einArrayList verwenden.

Kopieren wir zunächst die Werte in die Liste:

List employeeById = new ArrayList<>(map.values());

Und danach sortieren wir es:

Collections.sort(employeeById);

Denken Sie daran, dass dies funktioniert, weilEmployee implements the Comparable interface. Andernfalls müssten wir einen manuellen Komparator für unseren Aufruf vonCollections.sort definieren.

Um die Ergebnisse zu überprüfen, drucken wir dieemployeeById:

[Employee{id=1, name='Mher'},
Employee{id=2, name='George'},
Employee{id=8, name='John'},
Employee{id=22, name='Annie'}]

Wie wir sehen, werden die Objekte nach ihremid-Feld sortiert.

4. Verwenden vonTreeSet 

Falls wirdon’t want to accept duplicate values in our sorted collection, there is a nice solution with TreeSet.

Fügen wir zunächst einige doppelte Einträge zu unserer ursprünglichen Karte hinzu:

Employee employee5 = new Employee(1L, "Mher");
map.put(employee5.getName(), employee5);
Employee employee6 = new Employee(22L, "Annie");
map.put(employee6.getName(), employee6);

4.1. Nach Schlüssel sortieren

So sortieren Sie die Karte nach Schlüsseleinträgen:

SortedSet keySet = new TreeSet<>(map.keySet());

Drucken wir diekeySet und sehen die Ausgabe:

[Annie, George, John, Mher]

Jetzt haben wir die Kartenschlüssel ohne die Duplikate sortiert.

4.2. Nach Wert sortieren

Ebenso sieht der Konvertierungscode für die Kartenwerte wie folgt aus:

SortedSet values = new TreeSet<>(map.values());

Und die Ergebnisse sind:

[Employee{id=1, name='Mher'},
Employee{id=2, name='George'},
Employee{id=8, name='John'},
Employee{id=22, name='Annie'}]

Wie wir sehen können, enthält die Ausgabe keine Duplikate. This works with custom objects when we override equals and hashCode.

5. Verwenden von Lambdas und Streams

Since the Java 8, we can use the Stream API and lambda expressions to sort the map. Wir müssen lediglich die Methodesortedüber diestream -Spipeline der Karte aufrufen.

5.1. Nach Schlüssel sortieren

Zum Sortieren nach Schlüsseln verwenden wir dencomparingByKey -Scomparator:

map.entrySet()
  .stream()
  .sorted(Map.Entry.comparingByKey())
  .forEach(System.out::println);

Die letzte Stufe vonforEachdruckt die Ergebnisse aus:

Annie=Employee{id=22, name='Annie'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Mher=Employee{id=1, name='Mher'}

Standardmäßig ist der Sortiermodus aufsteigend.

5.2. Nach Wert sortieren

Natürlich können wir auch nach den Objekten vonEmployeeortieren:

map.entrySet()
  .stream()
  .sorted(Map.Entry.comparingByValue())
  .forEach(System.out::println);

Wie wir sehen, druckt der obige Code eine Karte aus, die nach denid-Feldern derEmployee-Objekte sortiert ist:

Mher=Employee{id=1, name='Mher'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Annie=Employee{id=22, name='Annie'}

Zusätzlich können wir die Ergebnisse in einer neuen Karte sammeln:

Map result = map.entrySet()
  .stream()
  .sorted(Map.Entry.comparingByValue())
  .collect(Collectors.toMap(
    Map.Entry::getKey,
    Map.Entry::getValue,
    (oldValue, newValue) -> oldValue, LinkedHashMap::new));

Note that we collected our results into a LinkedHashMap. Standardmäßig gibtCollectors.toMap eine neue HashMap zurück, aber wie wir wissen,HashMap doesn’t guarantee iterationorder,, währendLinkedHashMap dies tut.

6. Mit Guave

Eine Bibliothek, mit der wir dieHashMap sortieren können, ist Guava. Bevor wir beginnen, ist es hilfreich, unsere Angaben zumaps in Guava zu überprüfen.

Deklarieren wir zunächst einOrdering, da wir unsere Karte nachEmployee’sId Feld sortieren möchten:

Ordering naturalOrdering = Ordering.natural()
  .onResultOf(Functions.forMap(map, null));

Jetzt müssen wir nur nochImmutableSortedMap verwenden, um die Ergebnisse zu veranschaulichen:

ImmutableSortedMap.copyOf(map, naturalOrdering);

Und wieder ist die Ausgabe eine Karte, geordnet nach dem Feldid:

Mher=Employee{id=1, name='Mher'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Annie=Employee{id=22, name='Annie'}

7. Zusammenfassung

In diesem Artikel haben wir verschiedene Möglichkeiten zum Sortieren einesHashMap by-Schlüssels oder nach Wert untersucht.

Und wir haben uns genau angesehen, wie wir dies tun können, wenn das Attribut eine benutzerdefinierte Klasse ist, indem wirComparable implementieren.

Schließlich kann wie immer der während der Diskussion verwendete Codeover on GitHub gefunden werden.