使用 Java Streams 验证两个不同列表之间的内容时需要获取第二个列表排序

Sud*_*ina 4 java java-8 java-stream

我有一个用例,我将所有员工数据放在一个列表 ( List<Employee> employeesList) 中,我想通过提供另一个员工 ID ( List<String> employeeIdList)列表来获取所需的员工,我需要employeeIdList在检索后为员工提供相同的顺序。

我可以使用常规嵌套 for 循环来实现这一点,但我想检查使用 Java 流实现它的最佳方法是什么。

通过使用常规流,我没有得到正确的顺序,因此我尝试在迭代期间检查条件并将其添加到不同的列表中,但我仍然必须收集我真的没有在任何地方使用它们的对象。

是否有其他最佳选择来实现此功能。任何帮助表示赞赏。

下面是示例代码。

package com.test;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * The Class SimpleClass.
 */
public class SimpleClass {

    /**
     * The main method.
     *
     * @param args the arguments
     */
    public static void main(String[] args) {
        Employee employee1 = new Employee("1", "Employee 1");
        Employee employee2 = new Employee("2", "Employee 2");
        Employee employee3 = new Employee("3", "Employee 3");
        Employee employee4 = new Employee("4", "Employee 4");
        Employee employee5 = new Employee("5", "Employee 5");
        List<Employee> employeesList = new LinkedList<>();
        employeesList.add(employee5);
        employeesList.add(employee1);
        employeesList.add(employee2);
        employeesList.add(employee3);
        employeesList.add(employee4);

        List<String> neededEmployees = new LinkedList<>();

        neededEmployees.add("4");
        neededEmployees.add("1");
        neededEmployees.add("5");

        /* Nested For Loop */
        List<Employee> requiredEmployeesList = new LinkedList<>();
        for (String employeeId : neededEmployees) {
            for (Employee employee : employeesList) {
                if (employee.getId().equals(employeeId)) {
                    requiredEmployeesList.add(employee);
                }
            }
        }
        printEmployeeDetails(requiredEmployeesList);

        /* Using Streams - Not returning the required order */
        List<Employee> employeesListNew = employeesList.stream().filter(
                employee -> neededEmployees.stream().anyMatch(employeeId -> employeeId.equals(employee.getId())))
                .collect(Collectors.toList());

        printEmployeeDetails(employeesListNew);

        /* Using Streams - adding to a different list based on condition - This provides the right order as required*/
        List<Employee> sortedEmployeesList = new ArrayList<>();
        neededEmployees.stream()
                .filter(employeeId -> employeesList.stream()
                        .anyMatch(employee -> employee.getId().equals(employeeId) ? sortedEmployeesList.add(employee) : false))
                .collect(Collectors.toList());

        printEmployeeDetails(sortedEmployeesList);
    }

    /**
     * Prints the employee details.
     *
     * @param employeesList the employees list
     */
    private static void printEmployeeDetails(List<Employee> employeesList) {
        System.out.println("Printing Employees List");
        for (Employee employee : employeesList) {
            System.out.println(employee.getId());
            System.out.println(employee.getName());
        }
    }

}

class Employee {
    String id;
    String name;
    // Setter, Getter and AllArgsConstructor
}
Run Code Online (Sandbox Code Playgroud)

Nam*_*man 5

在不排序实际数据的情况下执行您正在寻找的操作的一种方法是使用 id 到员工本身的映射,例如:

Map<String, Employee> employeeMap = employeesList.stream()
        .collect(Collectors.toMap(Employee::getId, Function.identity()));
Run Code Online (Sandbox Code Playgroud)

然后将它们映射到基于neededEmployees以下的顺序迭代

List<Employee> requiredAndSortedEmployeesList = neededEmployees.stream()
        .map(employeeMap::get)
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

  • 使用映射是推荐的优化方式,但应该提到关键点:通过在第二个操作中迭代“neededEmployees”,我们按照“neededEmployees”的顺序得到结果。OP 的低效方法可以通过类似的方式修复,即通过流式传输“neededEmployees”并在中间操作中使用“employeesList”。 (2认同)