有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

具有可空值的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)表达式并编写“流式”的可能性:


共 (3) 个答案

  1. # 1 楼答案

    如果比较Optional<Long>而不是Long,则无需区分存在的对象和不存在的对象

    Optional<Long> root = Optional.of(basedOnObject.getObjectId());
    list.stream()
        .map(DbObject::getBasedOnObjectId)
        .map(Optional::ofNullable)
        .filter(root::equals)
        .collect(Collectors.toList());
    

    在这种情况下,它更简单,因为您可以颠倒比较:

    list.stream()
        .filter(o -> basedOnObject.getObjectId().equals(o.getBasedOnObjectId()))
        .collect(Collectors.toList());
    
  2. # 2 楼答案

    你不需要在这里介绍Optional。您只需要知道null在您的域中,并进行相应的处理。像这样:

    list.stream().filter(o -> Objects.equals(o.getBasedOnObjectId(), 
                                             basedOnObject.getObjectId()))
                 .collect(toList());
    

    或者通过显式地过滤空值(.filter(o -> o.getBasedOnObjectId() != null),或者通过将空值检查滚动到现有的过滤条件中

    没有理由让事情变得更复杂Objects.equals()可能是您想要的,只需使用它即可

  3. # 3 楼答案

    在将空对象传递给后续操作之前,您可能希望从流中实际删除这些空对象。尝试将对象映射到BasedOnObjectId表单,然后过滤空值:

    list.stream()
        .map(object -> object.getBasedOnObjectId())
        .filter(object -> object != null)
        ...