【发布时间】:2014-08-12 16:02:23
【问题描述】:
我试图用 java lambda 表达式替换现有循环。
我有一个简单的数据结构,如下所示:
class DbObject{
private Long objectId;
private Long basedOnObjectId; //<- this field can be null
public Long getObjectId() {
return objectId;
}
public void setObjectId(Long objectId) {
this.objectId = objectId;
}
public Long getBasedOnObjectId() {
return basedOnObjectId;
}
public void setBasedOnObjectId(Long basedOnObjectId) {
this.basedOnObjectId = basedOnObjectId;
}
}
然后我有一个 DbObjects 列表
我试图用指定的 basedOnObjectId 过滤每个 DbObject:
(1) list.stream().filter(object -> obejct.getBasedOnObjectId()
.equals(basedOnObject.getObjectId()))
.collect(Collector.of(List))
当然,这段代码给了我 NullPointer,因为一些 od DbObject 没有 BasedOnObjectId,因为它们是根。
所以很自然的事情是替换字段“Long basedOnObjectId;”可选,但正如我在开始时提到的那样,存在现有的生产代码,它不是快速修复。
所以我试图做出一些改变,我评估以下句子:
Optional<Long> option = Optional.ofNullable(objectWithNullBasedOnId.getBasedOnObjectId());
并尝试使用 .get() 方法或 .ifPresent() 但 .get() 也会抛出空指针异常,并且 ifPresent 不专用于流。
我注意到这一点,当我拥有带有 null basedOnObjectId 的 DbObject 时,我不必检查值是否完全为 null,而只需跳过这一步执行。
所以我决定使用 .orElse() 方法并返回一些假值。在这种情况下,我返回 0L 值,因为该索引在 DB 中不存在 :)
所以我的代码:
(2) List newList = list.stream().filter(object -> Optional.ofNullable(object.getBasedOnObjectId())
.orElse(0L)
.equals(basedOnObject.getObjectId()) )
.collect(Collectors.toList()) ;
在这种情况下,这可以正常工作,但我认为这是某种解决方法。在其他语言中,可以使用 null 值跳过执行,或者使用类似 skip-skipWhen 的方法。
我的问题是:是否有可能使用 java 8 中的专用方法(例如可选)实现 (2) 表达式的目标并编写“流式”:)
【问题讨论】:
-
你让它变得比它需要的更复杂。过滤掉空值:list.stream().filter(o -> o.basedOnObjectId() != null)...
-
或者,只使用 Objects.equal,它会为您处理 null。
标签: java lambda java-8 java-stream