Anleitung

Zwei Listen in Java vergleichen (gemeinsame, fehlende und gleiche Elemente)

Von 10 Min. Lesezeit

Zwei Listen zu vergleichen kommt in Java ständig vor: Datenbankeinträge synchronisieren, API-Antworten in Tests prüfen oder herausfinden, welche IDs zwischen zwei Exporten hinzugekommen oder weggefallen sind. Je nach Frage brauchen Sie ein anderes Werkzeug:

  • Sind die Listen gleich? – mit oder ohne Beachtung von Reihenfolge und Duplikaten
  • Welche Elemente stehen in beiden Listen? – die Schnittmenge
  • Welche Elemente stehen nur in einer Liste? – die Differenz

Diese Anleitung behandelt jeden Fall mit der Standardbibliothek (Java 16+ für Stream.toList() und Records) sowie mit Alternativen aus Apache Commons und Guava. Alle Codebeispiele verwenden diese Importe:

import java.util.*;
import java.util.stream.*;

Sie müssen zwei Listen nur einmal vergleichen? Fügen Sie sie in das kostenlose Tool zum Vergleichen zweier Listen ein und sehen Sie, was nur in A, nur in B und in beiden steht – ganz ohne Code.


1. Prüfen, ob zwei Listen gleich sind

List.equals() liefert nur dann true, wenn beide Listen dieselben Elemente in derselben Reihenfolge enthalten:

List<Integer> a = List.of(1, 2, 3);
List<Integer> b = List.of(1, 2, 3);
List<Integer> c = List.of(3, 2, 1);

System.out.println(a.equals(b)); // true
System.out.println(a.equals(c)); // false – same elements, different order

Die Elemente werden mit ihrer eigenen equals()-Methode verglichen. Das funktioniert also für Strings, Zahlen und jede Klasse, die equals() korrekt implementiert. Auch über Implementierungen hinweg: Eine ArrayList und eine LinkedList mit denselben Elementen sind gleich.


2. Listen ohne Beachtung der Reihenfolge vergleichen

Wie Sie die Reihenfolge ignorieren, hängt davon ab, ob Duplikate eine Rolle spielen.

Gleiche Elemente mit gleicher Häufigkeit (Duplikate zählen) – sortierte Kopien vergleichen:

List<Integer> x = Arrays.asList(3, 1, 2, 2);
List<Integer> y = Arrays.asList(2, 3, 2, 1);

List<Integer> sortedX = new ArrayList<>(x);
List<Integer> sortedY = new ArrayList<>(y);
Collections.sort(sortedX);
Collections.sort(sortedY);

System.out.println(sortedX.equals(sortedY)); // true

Lassen sich die Elemente nicht sortieren, vergleichen Sie stattdessen Häufigkeits-Maps:

Map<Integer, Long> countX = x.stream()
        .collect(Collectors.groupingBy(i -> i, Collectors.counting()));
Map<Integer, Long> countY = y.stream()
        .collect(Collectors.groupingBy(i -> i, Collectors.counting()));

System.out.println(countX.equals(countY)); // true

Gleiche unterschiedliche Elemente (Duplikate egal) – Sets vergleichen:

List<Integer> z = List.of(1, 2, 3);
System.out.println(new HashSet<>(x).equals(new HashSet<>(z))); // true

3. Gemeinsame Elemente (Schnittmenge) mit retainAll finden

retainAll() entfernt alle Elemente, die nicht in der anderen Collection stehen. Die Methode verändert die Liste, auf der sie aufgerufen wird – arbeiten Sie also mit einer Kopie:

List<String> listA = List.of("apple", "banana", "cherry", "date");
List<String> listB = List.of("banana", "date", "fig");

List<String> common = new ArrayList<>(listA);
common.retainAll(new HashSet<>(listB));

System.out.println(common); // [banana, date]

Die Kopie in eine neue ArrayList ist noch aus einem zweiten Grund wichtig: Mit List.of() oder Arrays.asList() erzeugte Listen unterstützen kein Entfernen, und retainAll() wirft dort eine UnsupportedOperationException.


4. Fehlende Elemente (Differenz) mit removeAll finden

removeAll() ist das Gegenteil: Die Methode entfernt alles, was in der anderen Collection steht, und lässt die Elemente übrig, die nur in der ersten Liste vorkommen:

List<String> onlyInA = new ArrayList<>(listA);
onlyInA.removeAll(new HashSet<>(listB));
System.out.println(onlyInA); // [apple, cherry]

List<String> onlyInB = new ArrayList<>(listB);
onlyInB.removeAll(new HashSet<>(listA));
System.out.println(onlyInB); // [fig]

Beide Methoden behalten die ursprüngliche Reihenfolge der Ausgangsliste bei, und übrig bleibende Elemente behalten ihre Duplikate.


5. Dasselbe mit Streams

Streams verändern die Quelllisten nicht und lesen sich gut, wenn Sie zusätzliche Filter brauchen:

Set<String> setB = new HashSet<>(listB);

List<String> onlyInA = listA.stream()
        .filter(item -> !setB.contains(item))
        .toList();                       // Java 16+; use collect(Collectors.toList()) before that

List<String> inBoth = listA.stream()
        .filter(setB::contains)
        .toList();

System.out.println(onlyInA); // [apple, cherry]
System.out.println(inBoth);  // [banana, date]

Um die Elemente zu erhalten, die in genau einer der Listen stehen (die symmetrische Differenz), kombinieren Sie beide Richtungen:

Set<String> setA = new HashSet<>(listA);

List<String> inOnlyOne = Stream.concat(
        listA.stream().filter(item -> !setB.contains(item)),
        listB.stream().filter(item -> !setA.contains(item)))
        .toList();

System.out.println(inOnlyOne); // [apple, cherry, fig]

Für einen Vergleich ohne Beachtung der Groß-/Kleinschreibung normalisieren Sie vor dem Aufbau des Sets – zum Beispiel listB.stream().map(String::toLowerCase).collect(Collectors.toSet()) – und schreiben jedes geprüfte Element ebenfalls klein.


6. Listen von Objekten vergleichen

Collections vergleichen Objekte mit equals() und – bei Hash-basierten Collections – mit hashCode(). Java-Records erzeugen beides aus ihren Feldern und funktionieren daher sofort:

record Customer(int id, String name) {}

List<Customer> oldCustomers = List.of(new Customer(1, "Ann"), new Customer(2, "Bob"));
List<Customer> newCustomers = List.of(new Customer(2, "Bob"), new Customer(3, "Cy"));

Set<Customer> newSet = new HashSet<>(newCustomers);
List<Customer> removed = oldCustomers.stream()
        .filter(c -> !newSet.contains(c))
        .toList();

System.out.println(removed); // [Customer[id=1, name=Ann]]

Bei einer normalen Klasse überschreiben Sie beide Methoden, equals() und hashCode() – überschreiben Sie nur equals(), findet ein HashSet passende Objekte nicht.

Oft möchten Sie Objekte über einen Schlüssel statt über alle Felder vergleichen, damit ein geänderter Name nicht als anderer Kunde zählt:

Set<Integer> newIds = newCustomers.stream()
        .map(Customer::id)
        .collect(Collectors.toSet());

List<Customer> removedById = oldCustomers.stream()
        .filter(c -> !newIds.contains(c.id()))
        .toList();

System.out.println(removedById); // [Customer[id=1, name=Ann]]

7. Hilfsbibliotheken: Apache Commons und Guava

Nutzt Ihr Projekt bereits eine dieser Bibliotheken, erledigen sie Mengenoperationen in einer Zeile.

Apache Commons Collections (org.apache.commons.collections4.CollectionUtils):

Collection<String> onlyInA = CollectionUtils.subtract(listA, listB);     // [apple, cherry]
Collection<String> inBoth = CollectionUtils.intersection(listA, listB);  // banana, date (any order)
Collection<String> inOnlyOne = CollectionUtils.disjunction(listA, listB); // apple, cherry, fig (any order)

Guava (com.google.common.collect.Sets) arbeitet mit Sets und liefert Live-Ansichten:

Set<String> setA = new HashSet<>(listA);
Set<String> setB = new HashSet<>(listB);

Set<String> onlyInA = Sets.difference(setA, setB);
Set<String> inBoth = Sets.intersection(setA, setB);
Set<String> inOnlyOne = Sets.symmetricDifference(setA, setB);

CollectionUtils berücksichtigt, wie oft jedes Element vorkommt; Guavas Sets arbeiten mit unterschiedlichen Elementen. Kopieren Sie eine Guava-Ansicht mit new HashSet<>(view), wenn sich die zugrunde liegenden Sets ändern.


8. Performance: Keine List-Suche in einer Schleife

list.contains() prüft Element für Element. ArrayList.removeAll(otherList) und filter(otherList::contains) vergleichen also jedes Element der einen Liste mit jedem Element der anderen. Bei zwei Listen mit je 100.000 Einträgen können das bis zu 10 Milliarden Vergleiche sein.

Wenn Sie die andere Liste – wie in allen Beispielen oben – zuerst in ein HashSet packen, wird jede Abfrage zu einer Operation mit konstanter Laufzeit, und der gesamte Vergleich braucht rund 100.000 Schritte:

// Slow: O(n × m)
listA.stream().filter(listB::contains).toList();

// Fast: O(n + m)
Set<String> lookup = new HashSet<>(listB);
listA.stream().filter(lookup::contains).toList();

Zusammenfassung

Ziel Empfohlener Weg Reihenfolge? Hinweise
Gleich, gleiche Reihenfolge a.equals(b) – Funktioniert über List-Implementierungen hinweg
Gleich, beliebige Reihenfolge, mit Duplikaten Sortierte Kopien oder Häufigkeits-Maps – Maps auch für nicht sortierbare Elemente
Gleich, beliebige Reihenfolge, ohne Duplikate new HashSet<>(a).equals(new HashSet<>(b)) – Ignoriert Wiederholungen
Gemeinsame Elemente copy.retainAll(new HashSet<>(b)) Ja Erst kopieren; List.of ist unveränderlich
Nur in A copy.removeAll(new HashSet<>(b)) oder Stream-Filter Ja Stream-Variante verändert nichts
In genau einer Liste Stream.concat beider Differenzen Ja Oder CollectionUtils.disjunction
Listen von Objekten Records oder equals() + hashCode() Ja Oder Vergleich über einen Schlüssel wie id

Beginnen Sie mit einer HashSet-Abfrage und einem Stream-Filter – schnell, ohne Ihre Listen zu verändern, und passend für fast jeden Fall. Für eine schnelle Prüfung außerhalb Ihres Codes erledigt das Online-Tool zum Listenvergleich dasselbe im Browser. Sie arbeiten mit Python? Lesen Sie Zwei Listen in Python vergleichen.

Tags

#Java#Listenvergleich#Anleitung

Über den Autor

songshiqiangUnabhängiger Entwickler

Entwickelt mit KI-Tools spannende Websites.

Ähnliche Beiträge

Anleitung

Zwei Listen in Google Tabellen vergleichen (Übereinstimmungen und Unterschiede)

Zwei Listen in Google Tabellen mit bedingter Formatierung, COUNTIF, MATCH, XLOOKUP und FILTER vergleichen: Übereinstimmungen hervorheben, fehlende Einträge markieren, Unterschiede in eine neue Liste extrahieren und Listen auf verschiedenen Tabellenblättern vergleichen.

9 Min. Lesezeit
#Google Tabellen#Listenvergleich#Anleitung
Weiterlesen
Anleitung

Zwei Listen in Python vergleichen (mit Beispielen)

Der komplette Leitfaden zum Vergleichen zweier Listen in Python: gemeinsame und unterschiedliche Elemente mit Sets finden, Reihenfolge mit List Comprehensions behalten, Listen auf Gleichheit prüfen, elementweise vergleichen, Listen von Dictionaries vergleichen und große Datenmengen mit pandas verarbeiten.

12 Min. Lesezeit
#Python#Listenvergleich#Anleitung
Weiterlesen
Anleitung

Zwei Listen in Excel vergleichen (Übereinstimmungen und Unterschiede finden)

Neun Wege, zwei Listen in Excel zu vergleichen: Übereinstimmungen mit bedingter Formatierung hervorheben, mit ZÄHLENWENN oder VERGLEICH markieren, mit SVERWEIS oder XVERWEIS nachschlagen, mit FILTER extrahieren, zeilenweise vergleichen und große Datenmengen mit Power Query verarbeiten.

12 Min. Lesezeit
#Excel#Listenvergleich#XVERWEIS#Anleitung
Weiterlesen