Ответ
Метод filter() в Java Stream API работает с функциональным интерфейсом Predicate<T>.
Почему именно Predicate?
Predicate<T>имеет единственный абстрактный методboolean test(T t), который принимает элемент потока и возвращаетboolean.- Если
test()возвращаетtrue, элемент проходит фильтр и остается в потоке; еслиfalse— элемент отбрасывается.
Пример использования:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Alex");
List<String> longNames = names.stream()
.filter(name -> name.length() > 3) // Лямбда-выражение для Predicate<String>
.collect(Collectors.toList());
// Результат: ["Alice", "Charlie", "Alex"]
Более сложный пример с составным предикатом:
Predicate<String> lengthPredicate = s -> s.length() > 3;
Predicate<String> startsWithAPredicate = s -> s.startsWith("A");
List<String> result = names.stream()
.filter(lengthPredicate.and(startsWithAPredicate))
.collect(Collectors.toList());
// Результат: ["Alice", "Alex"] Ответ 18+ 🔞
Давай разберём этот ваш filter(), а то некоторые до сих пор думают, что там какая-то магия, а не обычный Predicate<T>.
Вот смотри, вся суть в том, что Predicate<T> — это просто интерфейс с одним-единственным методом boolean test(T t). И вся его работа — сказать «да» или «нет», как бабка у подъезда: «Проходи, милок» или «А ну пошёл нахуй отсюда!». Если test() вернул true — элемент остаётся в потоке, если false — ему писец, вылетает к ебене матери.
Вот, например, у нас список имён, и мы хотим оставить только те, что длиннее трёх букв. Проще простого, ёпта:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Alex");
List<String> longNames = names.stream()
.filter(name -> name.length() > 3) // Это и есть наш Predicate, который проверяет длину
.collect(Collectors.toList());
// В итоге останутся: ["Alice", "Charlie", "Alex"]
А теперь представь, что ты хитрая жопа и хочешь проверять не по одному условию, а по двум сразу. Ну, типа, имя должно быть длиннее трёх букв И начинаться на «А». Да не вопрос, блядь! Можно предикаты комбинировать, как конструктор:
Predicate<String> lengthPredicate = s -> s.length() > 3;
Predicate<String> startsWithAPredicate = s -> s.startsWith("A");
List<String> result = names.stream()
.filter(lengthPredicate.and(startsWithAPredicate)) // Вот тут они склеились в один большой «заслон»
.collect(Collectors.toList());
// И что останется? Правильно, только ["Alice", "Alex"]. Bob и Charlie — в пизду, не прошли проверку.
Вот и вся философия, никакой ебалы-переебалы. Predicate решает — пропустить элемент дальше или послать его на три весёлых буквы. А ты сиди и радуйся, что не надо вручную писать циклы с кучей if-ов. Красота, да и только!