可选<List> Java 8 lambda表达式获取第一个元素

mes*_*eso 4 lambda optional java-8 java-stream

我是新手,在java 8流+ lambda中努力学习.有人可以用下面的代码帮助我吗?需要从列表中找到第一人的年龄是可选的.此列表可以为null.

缺少代码 - null检查列表的第一个元素.想要检查一下.

相当于下面一段代码的东西.

//input parameter 
//Optional<List<Person>> persons
public Integer getAgeOfFirstPerson(Optional<List<Person>> persons) {
    if (!persons.isPresent()) {
        return null;
    }

    Integer age = persons.get()
        .get(0)
        .getAge();

    return age;
}

//Person.java
class Person {
    Integer age;
    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

Did*_*r L 9

假设List你的内部Optional是空的,那么你也应该考虑这个案例.最简单的方法是:

return persons.flatMap(list -> list.stream().findFirst()).map(Person::getAge).orElse(null);
Run Code Online (Sandbox Code Playgroud)

这不幸的是不处理null的第一列表条目findFirst()抛出一个NullPointerException时的第一个元素Streamnull(如霍尔格在评论中说明).

因此,如果要跳过null列表条目并获取第一个非空的条目,请执行以下操作:

return persons.flatMap(list -> list.stream().filter(Objects::nonNull).findFirst())
              .map(Person::getAge)
              .orElse(null);
Run Code Online (Sandbox Code Playgroud)

否则,如果相反,你总是想要第一个条目,即使它是null,你可以像这样调整它:

return persons.flatMap(list -> list.stream().limit(1).filter(Objects::nonNull).findFirst())
              .map(Person::getAge)
              .orElse(null);
Run Code Online (Sandbox Code Playgroud)

但是这真的变得非常复杂,所以回到测试列表是否为空是更简单的:

return persons.filter(list -> !list.isEmpty())
              .map(list -> list.get(0))
              .map(Person::getAge)
              .orElse(null);
Run Code Online (Sandbox Code Playgroud)

  • 是的,可以将其推广到任何类型的具有可变数量元素(可能为零)的数据结构。这样的结构绝不能为“ null”,也绝不能包含“ null”,因为在大多数情况下,您可以通过不包含这些元素甚至根本不包含任何元素来表达相同的意思。因此,对于此问题的“列表”参数,首先不应将其设置为“可选”,因为列表可以为空而不是不存在。 (2认同)