我有一段代码在做这样的事情:
Optional<College> college = Optional.ofNullable(student)
.map(stud -> stud.getCollege())
.get()
.stream()
.filter(college -> Objects.nonNull(college.getCollegeName()))
.findFirst();现在,在编写单元测试时,我发现了一个陷阱,如果学生以null的身份来了怎么办?
这实际上就像:
Optional.empty() // the same as the student is null
.map(stud -> stud.getCollege())
.get()
.stream()
.filter(college -> Objects.nonNull(college.getCollegeName()))
.findFirst();我觉得这不太好因为我得到了例外
expected<com.src.exceptions.CollegeNotFoundException> but
was<java.util.NoSuchElementException>#更新
更新问题细节,以供澄清
发布于 2020-07-27 17:40:27
我同意@Nikolas的方法,只是您不应该返回null,返回null最终是反对使用Optional的
Optional<College> optional = Optional.ofNullable(student)
.map(stud -> stud.getCollegeList())
.orElse(Collections.emptyList())
.stream()
.filter(c -> Objects.nonNull(c.getCollegeName()))
.findFirst();发布于 2020-07-27 16:58:13
调用Optional::get而没有先前的check Optional::isPresent是危险的,因为它可能产生CollegeNotFoundException。这也不是使用Optional的方式。Optional的思想是映射/过滤值,并在Optional没有任何元素(空)的情况下提供默认值。
假设Student::getCollege返回具有College::getCollegeName方法的List<College>,则可以执行以下操作:
College college = Optional.ofNullable(student)
.map(stud -> stud.getCollege())
// if Optional is empty, then use an empty collection
.orElse(Collections.emptyList())
.stream()
.filter(c -> Objects.nonNull(c.getCollegeName()))
.findFirst()
// get the value or else college is null
.orElse(null);只要stud.getCollege()返回null,Optional就变为空,空列表将被流。此外,还应用了相同的原则:只要列表是空的,filter和findFirst就不会被调用,null就会安全地返回(或者您想要的任何默认值)。
还请注意,行.filter(c -> Objects.nonNull(c.getCollegeName()))也可能生成NullPointerException,只要没有保证stud.getCollege()不返回带有null元素的列表(请记住,列表本身不是null,因此Optional将其视为“有价值的”项)。安全代码实际上如下所示:
Optional<College> college = Optional.ofNullable(student)
.map(stud -> stud.getCollege())
.orElse(Collections.emptyList())
.stream()
.filter(c -> c != null && c.getCollegeName() != null)
.findFirst();实际上,我更喜欢返回一个空对象,null或Optional本身。
https://stackoverflow.com/questions/63119484
复制相似问题