MST
星途 面试题库

面试题:Java Stream filter自定义复杂过滤策略及并行流应用

有一个包含员工信息的List,员工类Employee包含属性department(部门,字符串类型)、performanceScore(绩效分数,浮点数类型)、yearsOfExperience(工作年限,整数类型)。现在需要定义一个复杂的过滤策略:如果部门是'R&D',则绩效分数要大于3.5且工作年限不少于3年;如果部门是'Marketing',则绩效分数要大于3.0且工作年限不少于2年。使用Java Stream的filter方法实现该过滤策略,同时考虑如何使用并行流来提高处理效率,并说明并行流在这种场景下可能存在的问题及解决方案。
14.5万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

class Employee {
    private String department;
    private double performanceScore;
    private int yearsOfExperience;

    public Employee(String department, double performanceScore, int yearsOfExperience) {
        this.department = department;
        this.performanceScore = performanceScore;
        this.yearsOfExperience = yearsOfExperience;
    }

    public String getDepartment() {
        return department;
    }

    public double getPerformanceScore() {
        return performanceScore;
    }

    public int getYearsOfExperience() {
        return yearsOfExperience;
    }
}

public class EmployeeFilter {
    public static List<Employee> filterEmployees(List<Employee> employees) {
        return employees.stream()
               .parallel()
               .filter(employee -> {
                    if ("R&D".equals(employee.getDepartment())) {
                        return employee.getPerformanceScore() > 3.5 && employee.getYearsOfExperience() >= 3;
                    } else if ("Marketing".equals(employee.getDepartment())) {
                        return employee.getPerformanceScore() > 3.0 && employee.getYearsOfExperience() >= 2;
                    }
                    return false;
                })
               .collect(Collectors.toList());
    }
}

并行流提高处理效率

在上述代码中,.parallel() 将顺序流转换为并行流。并行流会将数据分成多个部分,利用多核CPU并行处理每个部分,从而提高处理大量数据时的效率。

并行流可能存在的问题及解决方案

  1. 线程安全问题:如果在过滤操作中访问或修改共享状态,可能会导致线程安全问题。
    • 解决方案:避免在过滤操作中访问或修改共享状态。如果必须访问共享资源,可以使用线程安全的数据结构,如 ConcurrentHashMap 等。
  2. 性能问题:并行流的开销主要来自数据分割、任务调度和结果合并。如果数据量较小,并行流的开销可能会大于其带来的性能提升。
    • 解决方案:根据数据量大小进行测试和调整。对于小数据量,使用顺序流可能更高效;对于大数据量,并行流更有优势。
  3. 异常处理问题:并行流中抛出的异常处理较为复杂,因为异常可能在不同的线程中抛出。
    • 解决方案:可以使用 try - catch 块在并行流操作之后捕获异常,或者使用 peek 操作在流处理过程中进行异常处理,但这种方式相对复杂。建议在并行流操作之前对数据进行必要的预处理,尽量避免异常的发生。