可选<;列表>;Java8Lambda表达式获取第一个元素

可选<;列表>;Java8Lambda表达式获取第一个元素,lambda,java-8,java-stream,optional,Lambda,Java 8,Java Stream,Optional,我是这里的新手,正在努力学习Java8 streams+lambda。有人能帮我完成下面的代码吗?需要从列表中找到第一个人的年龄,这是可选的。此列表可能为空 列表第一个元素的代码-空检查中缺少。我也想要这张支票 与下面的代码相当的东西 //input parameter //Optional<List<Person>> persons public Integer getAgeOfFirstPerson(Optional<List<Person>>

我是这里的新手,正在努力学习Java8 streams+lambda。有人能帮我完成下面的代码吗?需要从列表中找到第一个人的年龄,这是可选的。此列表可能为空

列表第一个元素的代码-空检查中缺少。我也想要这张支票

与下面的代码相当的东西

//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
}
//输入参数
//可选人员
公共整数getAgeOfFirstPerson(可选人员){
如果(!persons.isPresent()){
返回null;
}
整数年龄=persons.get()
.get(0)
.getAge();
回归年龄;
}
//Person.java
班主任{
整数年龄;
//接球手和接球手
}

您可以使用
可选.map

public int getAgeOfFirstPerson(Optional<List<Person>> persons){ 
    return persons.map(people -> people.get(0).getAge()).orElse(0);
}
public-int-getageofficerstperson(可选人员){
返回persons.map(people->people.get(0.getAge()).orElse(0);
}
请注意,原语没有
null
(它们不是对象),因此已将其替换为
0


或者进一步改进为,如果需要检查Person是否为null。

返回null
如果
int
是返回类型,则不会编译。假设您想要一个缺席的
可选的

return persons.map(list -> list.get(0)).map(Person::getAge)
将起作用(不幸的是,对于流没有类似的
mapToInt
返回
OptionalInt
)。需要两个
map
s来处理

列表第一个元素的代码-空检查中缺少。我也想要这张支票


假设您的
可选
中的
列表
可以为空,那么您也应该考虑这种情况。因此,最简单的方法是:

return persons.flatMap(list -> list.stream().findFirst()).map(Person::getAge).orElse(null);
不幸的是,当
的第一个元素为
null
(如霍尔格在注释中所述)时,
findFirst()
抛出
NullPointerException
时,它不会处理
null
第一个列表项

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

return persons.flatMap(list -> list.stream().filter(Objects::nonNull).findFirst())
              .map(Person::getAge)
              .orElse(null);
否则,如果您总是想要第一个条目,即使它是
null
,您可以这样调整它:

return persons.flatMap(list -> list.stream().limit(1).filter(Objects::nonNull).findFirst())
              .map(Person::getAge)
              .orElse(null);
然而,这确实变得非常复杂,因此只需返回测试列表是否为空就更简单了:

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

我引述,不要使用“谢谢”作为注释:)可能更具争议性,但您可能应该避免使用
可选>
和包含空
列表的非空列表?如果没有,则根本不要使用
可选
,而是使用空的
列表
。如果是,也许你应该定义你自己的类型来清楚地描述它。@DiDierrl我不同意“如果是”部分:
Optional@AlexeyRomanov“
选项”编辑了代码。我更喜欢返回整数。然后只需在末尾添加
.orElse(null)
。尽管正如迪迪尔指出的,这忽略了“列表为空”如果列表为空,则case.list->list.get(0)将抛出索引超出绑定异常:(@shakeel在Didier的答案中看到了最后一个版本。@Holger,我已经忘记了。我认为建议也应该避免流中的
null
项。无论如何,我已经相应地更新了答案。是的,这可以推广到任何具有可变元素数的数据结构,包括可能为零的元素。例如结构不应该是
null
,也不应该包含
null
,因为在大多数用例中,您可以通过不包含这些元素或者甚至不包含任何元素来表达相同的内容。因此,对于这个问题的
列表
参数,它首先不应该是
可选的
,因为列表可以是空的,而不是不存在的。@H奥尔格,我非常同意你