In Java 8 mit Streams ist das eigentlich ziemlich einfach. BEARBEITEN: Kann ohne Streams effizient sein, siehe unten.
List<String> listA = Arrays.asList("2009-05-18","2009-05-19","2009-05-21");
List<String> listB = Arrays.asList("2009-05-18","2009-05-18","2009-05-19","2009-05-19",
"2009-05-20","2009-05-21","2009-05-21","2009-05-22");
List<String> result = listB.stream()
.filter(not(new HashSet<>(listA)::contains))
.collect(Collectors.toList());
Beachten Sie, dass der Hash-Satz nur einmal erstellt wird: Die Methodenreferenz ist an die enthaltene Methode gebunden. Um dasselbe mit Lambda zu tun, müsste die Menge in einer Variablen enthalten sein. Das Erstellen einer Variablen ist keine schlechte Idee, insbesondere wenn Sie sie unansehnlich oder schwerer zu verstehen finden.
Sie können das Prädikat ohne diese Dienstprogrammmethode (oder explizite Umwandlung) nicht einfach negieren , da Sie die Negativmethodenreferenz nicht direkt aufrufen können (Typinferenz ist zuerst erforderlich).
private static <T> Predicate<T> not(Predicate<T> predicate) {
return predicate.negate();
}
Wenn Streams eine filterOut
Methode oder etwas anderes hätten, würde es besser aussehen.
Auch @Holger gab mir eine Idee. ArrayList
hat seine removeAll
Methode für mehrere Entfernungen optimiert, es ordnet seine Elemente nur einmal neu. Es wird jedoch die contains
von der angegebenen Sammlung bereitgestellte Methode verwendet , sodass wir diesen Teil optimieren müssen, wenn er listA
alles andere als winzig ist.
Mit listA
und listB
zuvor deklariert benötigt diese Lösung kein Java 8 und ist sehr effizient.
List<String> result = new ArrayList(listB);
result.removeAll(new HashSet<>(listA));