具有可空值的java筛选列表
我试图用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,因为它们是根
所以,很自然的事情是替换字段“长基线对象”可选,但正如我在开始时提到的,有现有的生产代码,这不是快速修复
所以我试着做一些改变,我评估以下句子:
Optional<Long> option = Optional.ofNullable(objectWithNullBasedOnId.getBasedOnObjectId());
试试看。get()方法或。ifPresent()但是。get()还引发空指针异常,并且ifPresent不专用于处理流
我注意到了这一点,并且当我使用null basedOnObjectId的DbObject时,我不必检查值是否完全为null,只需跳过执行的这一步
所以我决定使用。方法并返回一些伪值。在这种情况下,我返回0L值,因为此索引在数据库中不存在:)
所以我的代码是:
(2) List newList = list.stream().filter(object -> Optional.ofNullable(object.getBasedOnObjectId())
.orElse(0L)
.equals(basedOnObject.getObjectId()) )
.collect(Collectors.toList()) ;
在这种情况下,这是正确的,但我认为这是一种解决办法。在其他语言中,可以使用空值跳过执行,或者使用一些类似SkippWhen的方法
我的问题是:如果存在使用Java8中的专用方法(示例中为可选方法)实现(2)表达式并编写“流式”的可能性:
# 1 楼答案
如果比较
Optional<Long>
而不是Long
,则无需区分存在的对象和不存在的对象在这种情况下,它更简单,因为您可以颠倒比较:
# 2 楼答案
你不需要在这里介绍
Optional
。您只需要知道null在您的域中,并进行相应的处理。像这样:或者通过显式地过滤空值(
.filter(o -> o.getBasedOnObjectId() != null
),或者通过将空值检查滚动到现有的过滤条件中没有理由让事情变得更复杂
Objects.equals()
可能是您想要的,只需使用它即可# 3 楼答案
在将空对象传递给后续操作之前,您可能希望从流中实际删除这些空对象。尝试将对象映射到BasedOnObjectId表单,然后过滤空值: