【问题标题】:how to handle Optional Object in java streams api?java - 如何处理java流api中的可选对象?
【发布时间】:2019-04-03 08:13:25
【问题描述】:

我正在做简单的测试。

@Test
    public void whenFilterEmployees_thenGetFilteredEmployees(){
        Integer[] empIds = {1,2,3};
        List<Optional<Employee>> employees = Stream.of(empIds)
                .map(employeeRepository::findById)
                .collect(Collectors.toList());

        List<Employee> employeeList = employees
                .stream().filter(Optional::isPresent)
                .map(Optional::get)
                .filter(e->e !=null)
                .filter(e->e.getSalary()>200000)
                .collect(Collectors.toList());

        assertEquals(Arrays.asList(arrayOfEmps[2]), employeeList);


    }

我的员工表包含数据:

1   Jeff Bezos  100000
2   Bill Gates  200000
3   Mark Zuckerberg 300000

当前测试运行成功。

如您所见,我准备了两个员工列表,即员工和员工列表

我这样做是因为findById 方法返回可选。我如何使用流 api 以便我可以简单地获取员工列表

List<Employee> employeeList= ....

【问题讨论】:

  • 没有理由拆分两个流。只需使用一个,请求数据库,过滤(如果存在),应用其他过滤器,然后收集到列表。
  • @LuisG。不是重复的,因为问题不是在问这个问题。

标签: java java-stream


【解决方案1】:

只需合并两个流管道,即

List<Employee> employees = Stream.of(empIds)
                                 .map(employeeRepository::findById)
                                 .filter(Optional::isPresent)
                                 .map(Optional::get)
                               //.filter(e->e !=null) not needed as it's redundant
                                 .filter(e->e.getSalary()>200000)
                                 .collect(Collectors.toList());

【讨论】:

  • 有效吗?因为我无法从 .filter(Optional::isPresent) 上的静态上下文中引用非静态方法
  • @sagarlimbu 在我的手机 atm 上,但我看不出它不应该编译的原因。可能是类型推断问题...您使用的是什么 IDE?
  • 对不起,我没有正确看到您的答案。我实际上使用了 filter(Optional::get) 而不是 .map(Optional::get)。
【解决方案2】:

我们可以使用Optional.stream(需要Java 9+)编写更短的代码:

List<Employee> employees = Stream.of(empIds)
        .flatMap(id -> employeeRepository.findById(id).stream())
        .filter(e -> e.getSalary() > 200000)
        .collect(Collectors.toList());

根据JavaDocOptional.stream

返回仅包含该值的顺序Stream,否则 返回一个空的Stream

因此我们可以立即进行filter 操作。

【讨论】:

  • @Holger 将此添加到我的答案中。谢谢。
  • 只需阅读您的comment 关于“方法引用过度使用”:)。正如我写的如何让代码更短,只有遵循你的建议是一致的。更新了我的答案。
  • 好吧,我不会认为两个方法引用“过度使用”。当mapflatMap 步骤可以合并时,更容易被忽略。这是一个不同的野兽,随后有四个 map 步骤......
  • 难道你还需要检查 null,因为 op 检查 null 吗?
  • 正确。 Optional.isPresentJavaDoc 表示:“如果存在值,则返回 true,否则返回 false。”所以如果Optional 为空,过滤器将不会通过。但是如果通过了,那么调用Optional.getvalue returned is not null 是安全的。
猜你喜欢
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
  • 2021-05-06
  • 1970-01-01
相关资源
最近更新 更多