Статьи

Как использовать метод filter () в Java 8

Интерфейс Java 8 Stream представляет метод filter() который можно использовать для фильтрации некоторых элементов из коллекции объектов на основе определенного условия. Это условие должно быть указано как предикат, который метод filter() принимает в качестве аргумента.

Интерфейс java.util.function.Predicate определяет абстрактный метод с именем test() который принимает объект универсального типа T и возвращает логическое значение.

Давайте сделаем некоторое кодирование, чтобы понять метод фильтра более четко. Посмотрите на следующий класс Блюдо.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Dish {
 
     private String name;
     private Boolean vegitarian;
     private Integer calaries;
     private Type type;
  
     public Dish(String name, Boolean vegitarian, Integer calaries, Type type) {
          super();
          this.name = name;
          this.vegitarian = vegitarian;
          this.calaries = calaries;
          this.type = type;
     }
 
     public Boolean getVegitarian() {
         return vegitarian;
     }
 
     public void setVegitarian(Boolean vegitarian) {
         this.vegitarian = vegitarian;
     }
 
     public Type getType() {
         return type;
     }
 
     public void setType(Type type) {
         this.type = type;
     }
 
     public enum Type { MEAT, FISH, OTHER };
}

Давайте подумаем, мы хотим отфильтровать только вегетарианские блюда из списка всех блюд. Ниже приводится подход до Java 8.

1
2
3
4
5
6
List<Dish> vegetarianDishes = new ArrayList<Dish>();
    for(Dish d: menu) {
       if(d.getVegetarian()) {
          vegetarianDishes.add(d);
       }
    }

Вышеуказанный подход называется внешней итерацией, которой мы явно управляем итерацией по сбору данных.

Как это можно сделать с Java 8? Это просто вопрос одной строки следующим образом.

1
2
3
4
List<Dish> menu = ....
List<Dish> vegitarianDishes = menu.stream()
                                    .filter(d -> d.getVegitarian())
                                    .collect(Collectors.toList());

Мы передали экземпляр Predicate в метод filter() в форме лямбда-выражения.

Кроме того, мы можем использовать ссылки на метод java 8 для передачи экземпляра Predicate методу filter() следующим образом.

1
2
3
4
List<Dish> menu = ....
List<Dish> vegitarianDishes = menu.stream()
                                    .filter(Dish::getVegitarian)
                                    .collect(Collectors.toList());

Dish::getVegitarian — это синтаксис для ссылок на методы Java 8. Это относится к getVegitarian() класса Dish.

Метод filter() возвращает Stream of Dishes, а метод collect() преобразует Stream в список. Операция сбора называется операцией терминала.

Допустим, мы хотим получить первые три блюда, которые содержат более 300 калорий. Потоки поддерживают метод limit(n) , который возвращает другой поток, длина которого не превышает заданный размер. Запрашиваемый размер передается в качестве аргумента для ограничения.

1
2
3
4
5
List<Dish> menu = ....
List<Dish> threeHighCalaricDish = menu.stream()
                                         .filter(d -> d.getCalaries() > 300)
                                         .limit(3)
                                         .collect(Collectors.toList());

Точно так же, если мы хотим пропустить первые 3 элемента, потоки поддерживают метод skip(n) для возврата потока, который отбрасывает первые n элементов. Если в потоке меньше элементов, чем n, возвращается пустой поток. Обратите внимание, что limit(n) и skip(n) дополняют друг друга!

Теперь упражнение для вас! Как бы вы использовали потоки для фильтрации первых двух мясных блюд?

1
2
3
4
5
List<Dish> menu = ....
List<Dish> meatDishes = menu.stream()
                                  .filter(d -> d.getType() == Dish.Type.MEAT)
                                  .limit(2)
                                  .collect(Collectors.toList())
Опубликовано на Java Code Geeks с разрешения Семики Калуге, партнера нашей программы JCG. Смотрите оригинальную статью здесь: Как использовать метод filter () в Java 8

Мнения, высказанные участниками Java Code Geeks, являются их собственными.