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 filterOutMethode oder etwas anderes hätten, würde es besser aussehen.
Auch @Holger gab mir eine Idee. ArrayListhat seine removeAllMethode für mehrere Entfernungen optimiert, es ordnet seine Elemente nur einmal neu. Es wird jedoch die containsvon der angegebenen Sammlung bereitgestellte Methode verwendet , sodass wir diesen Teil optimieren müssen, wenn er listAalles andere als winzig ist.
Mit listAund listBzuvor deklariert benötigt diese Lösung kein Java 8 und ist sehr effizient.
List<String> result = new ArrayList(listB);
result.removeAll(new HashSet<>(listA));