В Java 8 с потоками на самом деле все довольно просто.
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());
Обратите внимание, что хэш-набор создается только один раз: ссылка на метод привязана к его содержащему методу. Чтобы сделать то же самое с лямбдой, нужно было бы иметь набор в переменной. Создание переменной не является плохой идеей, особенно если вы считаете ее неприглядной или трудной для понимания.
Вы не можете легко отрицать предикат без чего-либо подобного этому вспомогательному методу (или явному приведению), так как вы не можете напрямую вызвать ссылку на метод отрицания (сначала необходимо определить тип). *
private static <T> Predicate<T> not(Predicate<T> predicate) {
return predicate.negate();
}
Если бы у потоков был метод filterOut
или что-то подобное, это выглядело бы лучше.