Научитесь использовать метод Stream.filter(Predicate) для обхода всех элементов и фильтрации всех элементов, которые соответствуют заданному условию, с помощью аргумента Predicate.
- Метод filter()
- Примеры Java Stream filter()
2.1. Фильтрация потока с использованием Лямбда-выражения
2.2. Фильтрация потока с использованием пользовательского предиката
2.3. Фильтрация и формирование списка
2.4. Пример потока с filter() и map()
2.5. Поток и filter() с методом, вызывающим исключение
Метод filter()
Синтаксис метода stream() выглядит следующим образом:
Stream<T> filter(Predicate<? super T> condition)
Предикат представляет собой функциональный интерфейс и предоставляет условие для фильтрации несоответствующих элементов из потока.
- filter() — это операция промежуточного потока.
- Он возвращает поток, состоящий из элементов данного потока, которые соответствуют заданному предикату.
- Аргумент filter() должен быть предикатом без состояния, который применяется к каждому элементу в потоке, чтобы определить, следует ли его включать или нет.
- Предикат — это функциональный интерфейс. Итак, мы также можем передать лямбда-выражение.
- Он возвращает новый поток, чтобы мы могли использовать другие операции, применимые к любому потоку.
Примеры Java Stream filter()
Фильтрация потока с использованием Лямбда-выражения
В этом примере мы выполняем итерацию по потоку чисел. Мы найдем все четные числа из потока и выведем их в консоль.
Встроенный предикат ‘n -> n % 2 == 0‘ является лямбда-выражением.
import java.util.Arrays;
import java.util.List;
public class Main
{
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
list.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
}
}
Вывод программы:
2
4
6
8
10
Фильтрация потока с использованием пользовательского предиката
Этот пример представляет собой вариацию первого примера. Он использует класс предикатов вместо лямбда-выражения, хотя и то, и другое — одно и то же.
Обратите внимание, что мы можем записать любое условие внутри предиката, чтобы оно соответствовало бизнес-требованиям.
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Main
{
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Predicate<Integer> condition = new Predicate<Integer>()
{
@Override
public boolean test(Integer n) {
if (n % 2 == 0) {
return true;
}
return false;
}
};
list.stream().filter(condition).forEach(System.out::println);
}
}
Вывод программы:
246810
Фильтрация и формирование списка
Мы можем использовать collect(Collectors.toList()) метод для сбора потока отфильтрованных элементов в список.
Этот пример снова является вариацией первого примера. Здесь мы собираем четные числа в список, а не выводим их на консоль.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main
{
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = list.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println(evenNumbers);
}
}
Вывод программы:
[2, 4, 6, 8, 10]
Пример потока с filter() и map()
Мы можем использовать метод map() для сбора элементов потока, возведения каждого числа в нем в квадрат, а затем формирования списока.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main
{
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = list.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.collect(Collectors.toList());
System.out.println(evenNumbers);
}
}
Вывод программы:
[4, 16, 36, 64, 100]
Поток и filter() с методом, вызывающим исключение
Методы, используемые в предикатах, возвращают логическое значение. Эти методы обычно выполняют простые сравнения значений и не выдают никаких исключений.
Но иногда нам может потребоваться иметь дело с такими методами, которые выдают исключение, и этот метод должен использоваться в предикате.
Чтобы решить эту проблему, мы должны использовать оператор try-catch для перехвата проверяемого исключения. Затем у нас есть выбор: либо обработать исключение, либо заново вызвать исключение.
Ниже приведен пример кода для обработки исключений, генерируемых методом, который был использован в предикате.
List<Integer> evenNumbers = list.stream()
.filter(a -> {
try {
return a.someMethodThrowingCheckedException();
} catch (IOException e) {
throw new UncheckedException(e);
}
})
.collect(Collectors.toList());