【问题标题】:How to filter map collection with helper method usage which prevent nullPointerException如何使用防止 nullPointerException 的辅助方法使用过滤地图集合
【发布时间】:2020-01-19 04:50:04
【问题描述】:

我有一个类似的方法:

static List<Employee> getEmployeesByFactoryAndTask(
      ProtectedMap<String, Factory> factoryMap, String factoryName, Task task) {

    return factoryMap.values().stream()
        .filter(factory -> factory.getName().equals(factoryName))
        .map(Factory::getEmployees)
        .flatMap(Optional::stream)
        .flatMap(Collection::stream)
        .filter(employee -> employee.getTask().equals(task))
        .collect(Collectors.toList());
  }

假设过滤器 Employees 集合由 factoryNameTask 枚举参数。

上面的代码工作正常,但我想在我的 ProtectedMap 类中使用辅助方法find

public class ProtectedMap<T, U> extends HashMap<T, U> {
    public Optional<U> find(T key) {
        return Optional.ofNullable(super.get(key));
    }
}

得到相同的结果。

到目前为止,我的方法如下所示:

return factoryMap
        .find(factoryName)
        .stream()
        .map(Factory::getEmployees)
        .flatMap(Optional::stream)
        .flatMap(Collection::stream)
        .collect(Collectors.toMap(Employee::getTask, Function.identity()));

但我不知道我想把第二个方法调用find 放在哪里,它会被Task 过滤以获得desribale 效果。附带说明一下,Factory 包含两个字段:Optional&lt;List&lt;Employees&gt;&gt;String,这是工厂的名称。 对于如何解决问题的建议,我将不胜感激。

【问题讨论】:

  • 您真正想要实现的目标是什么?您希望给定工厂的所有员工都有给定的任务?
  • 是的,我想要一个使用 find 方法 Usage 按两个条件过滤的员工列表。
  • 首先,阻止Factory 将集合包装成可选项。一个空集合已经足以表明没有元素。然后,您可以使用return factoryMap .find(factoryName) .map(f -&gt; f.getEmployees().stream().collect(Collectors.toMap( Employee::getTask, Function.identity()))) .orElse(Collections.emptyMap());
  • 不惜一切代价尝试引入那种琐碎的find 方法是没有意义的。如果你想要一个特定的任务,根本不要收集到Map:而不是.collect(Collectors.toMap(Employee::getTask, Function.identity())),使用.filter(employee -&gt; employee.getTask().equals(task)) .collect(Collectors.toList())
  • 我的第二条评论独立于“包含在可选列表中的列表”问题。只需使用return factoryMap .find(factoryName) .stream() .flatMap(f -&gt; f.getEmployees().map(Collection::stream).orElse(null)) .filter(employee -&gt; employee.getTask().equals(task)) .collect(Collectors.toList());

标签: java functional-programming java-stream java-11


【解决方案1】:

下面是处理您要求的代码,但getEmployeesByFactoryAndTask 也返回Optional&lt;List&lt;Employee&gt;&gt;,据我所知,这个返回值可以由您处理。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import java.util.Optional;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;


enum Task {
    QA, DEVELOPEMENT, DESIGN
}

class Employee {
    long id;
    String name;
    Task task;

    Employee(long id, String name, Task task) {
        this.id = id;
        this.name = name;
        this.task = task;
    }

    Task getTask() {
        return task;
    }
}

class Factory {
    List<Employee> employees;

    Factory() {}

    Factory(List<Employee> employees) {
        this.employees = employees;
    }

    public Optional<List<Employee>> getEmployees() {
        return Optional.ofNullable(employees);
    }
}

class ProtectedMap<T, U> extends HashMap<T, U> {
    public Optional<U> find(T key) {
        return Optional.ofNullable(super.get(key));
    }
}

public class Main57989215 {

    public static void main(String[] args) {
        List<Employee> employees1 = new ArrayList<>();
        employees1.add(new Employee(21, "Alen", Task.DESIGN));
        employees1.add(new Employee(31, "Herry", Task.QA));
        employees1.add(new Employee(41, "John", Task.DEVELOPEMENT));
        employees1.add(new Employee(51, "Martin", Task.QA));
        employees1.add(new Employee(61, "Jack", Task.DESIGN));


        List<Employee> employees2 = new ArrayList<>();
        employees2.add(new Employee(121, "John", Task.DESIGN));
        employees2.add(new Employee(131, "Porter", Task.QA));
        employees2.add(new Employee(141, "Cena", Task.DEVELOPEMENT));
        employees2.add(new Employee(151, "Luther", Task.QA));
        employees2.add(new Employee(161, "Dinga", Task.DESIGN));


        ProtectedMap<String, Factory> factoryMap = new ProtectedMap<>();
        factoryMap.put("factory1", new Factory(employees1));
        factoryMap.put("factory2", new Factory(employees2));
        factoryMap.put("factory3", new Factory());

        System.out.println(getEmployeesByFactoryAndTask(factoryMap, "factory1", Task.QA));
        System.out.println(getEmployeesByFactoryAndTask(factoryMap, "factory1", Task.QA));
        System.out.println(getEmployeesByFactoryAndTask(factoryMap, "factory2", Task.DEVELOPEMENT));
        System.out.println(getEmployeesByFactoryAndTask(factoryMap, "factory3", Task.DESIGN));
        System.out.println(getEmployeesByFactoryAndTask(factoryMap, "factory4", Task.QA));
    }

    static Optional<List<Employee>> getEmployeesByFactoryAndTask(ProtectedMap<String, Factory> factoryMap, String factoryName, Task task) {
        return Optional.ofNullable(factoryMap.find(factoryName)).orElse(Optional.empty())
                .flatMap(factory -> Optional.ofNullable(factory.getEmployees())
                        .orElse(Optional.empty()).map(employees -> employees.stream()
                                .filter(employee -> employee.getTask().equals(task)).collect(Collectors.toList())));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    相关资源
    最近更新 更多