«1. Обзор

В этом кратком руководстве мы узнаем, как находить элементы из одного списка на основе значений из другого списка с использованием потоков Java 8.

2. Использование потоков Java 8

Начнем с двух классов сущностей — Employee и Department:

class Employee {
    Integer employeeId;
    String employeeName;

    // getters and setters
}

class Department {
    Integer employeeId;
    String department;

    // getters and setters
}

Идея здесь состоит в том, чтобы отфильтровать список объектов Employee на основе списка объектов Department. В частности, мы хотим найти всех сотрудников из списка, который:

    имеет «продажи» в качестве своего отдела и имеет соответствующий идентификатор сотрудника в списке отделов

И для этого мы на самом деле отфильтруем одного внутри другой:

@Test
public void givenDepartmentList_thenEmployeeListIsFilteredCorrectly() {
    Integer expectedId = 1002;

    populate(emplList, deptList);

    List<Employee> filteredList = emplList.stream()
      .filter(empl -> deptList.stream()
        .anyMatch(dept -> 
          dept.getDepartment().equals("sales") && 
          empl.getEmployeeId().equals(dept.getEmployeeId())))
        .collect(Collectors.toList());

    assertEquals(1, filteredList.size());
    assertEquals(expectedId, filteredList.get(0)
      .getEmployeeId());
}

После заполнения обоих списков мы просто передаем объекты Stream of Employee объектам Stream of Department.

Далее, чтобы отфильтровать записи на основе наших двух условий, мы используем предикат anyMatch, внутри которого мы объединили все заданные условия.

Наконец, мы собираем результат в filteredList.

3. Заключение

В этой статье мы узнали, как:

    Передавать значения одного списка в другой список с помощью потока Collection# и Объединять несколько условий фильтрации с помощью предиката anyMatch()

Полный исходный код этого примера доступен на GitHub.