【问题标题】:How can I return boolean value using Optional.ifPresent如何使用 Optional.ifPresent 返回布尔值
【发布时间】:2023-03-13 15:40:02
【问题描述】:

我在使用Optional.ifPresent 语句时遇到了一些问题。我想减少NullPointerExceptions 的数量,所以我决定使用Optional 值。

我还试图避免if 声明反模式的阶梯。

所以我实现了Optional.isPresent 语句。但这并不是我所期望的。

请查看以下列表:

这是我服务的一部分:

    if (getAllComputerProducers().isPresent()) {
        if (isComputerProducerAlreadyExist(computerProducer))
            return new ResponseEntity<>(HttpStatus.CONFLICT);
    }

    computerProducerRepository.save(computerProducer);
    return new ResponseEntity<>(HttpStatus.CREATED);

getAllComputerProducers 函数如下所示:

private Optional<List<ComputerProducer>> getAllComputerProducers() {
    return Optional.ofNullable(computerProducerRepository.findAll());
}

如您所见,此函数返回Optional of List

isComputerProducerAlreadyExist 函数是这样实现的:

private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer) {
    return getAllComputerProducers()
            .get()
            .stream()
            .anyMatch(producer -> producer.getProducerName()
                    .equalsIgnoreCase(computerProducer.getProducerName()));
}

代码太多了,我相信它可以变得更简单。 我的目标是将代码减少为一行命令,例如:

getAllCimputerProducers().ifPresent(***and-here-some-anyMatch-boolean-function***)

但我无法在其中插入返回某些内容的函数。我该怎么做?

大家好 :)

【问题讨论】:

  • 你不能从你调用ifPresent的方法返回,从内部ifPresent:这是lambdas的一个基本限制。您只需使用if 检查isPresent(),然后在块中返回。
  • ifPresent 没有返回值。
  • From a Java Language Architect: "例如,你可能永远不应该将它用于返回结果数组或结果列表的东西;而是返回一个空数组或列表。 i>"
  • 但我也不能这样做:getAllSomething().ifPresent().stream().anyMatch(something-here) 我想检查列表中的某些内容是否与给定的参数匹配该函数,但仅当列表存在时。
  • 干净的代码规则之一:永远不要通过函数返回 NULL。而是抛出异常。如果使用此规则,则根本不需要使用 Optional。

标签: java spring optional


【解决方案1】:

你可以试试

private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer){
    return this.getAllComputerProducers()
            .map((List<ComputerProducer> computerProducers) -> computerProducers.stream()
                    .anyMatch(producer -> producer.getProducerName().equalsIgnoreCase(computerProducer.getProducerName())))
            .orElse(Boolean.FALSE);
}

或者不是加载所有计算机生产者,而是只加载使用其名称的那些。

private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer){
    return computerProducerRepository.findByName(computerProducer.getProducerName()).isEmpty();
}

据我所知,Spring 还支持存储库的“现有”方法,甚至不需要加载实体。

【讨论】:

  • 我不确定我是如何完全忽略最后一句话的。但至少我可以confirm Spring Data JPA 1.11 支持它。
【解决方案2】:

您可以将computerProducer.getProducerName() 传递给存储库以获取现有记录。方法名称将为'findByProducerName(String producerName)',如果 producerName 具有唯一约束,则返回类型将为Optional&lt;ComputerProducer&gt;,否则为Optional&lt;List&lt;ComputerProducer&gt;&gt;。但是,JPA 返回的是空列表而不是 null,因此列表上的可选不是必需的。

【讨论】:

    【解决方案3】:

    以下应该可以工作,但我没有任何东西可以编译它。

    Predicate<ComputerProducer> cpPredicate = producer -> producer.getProducerName().equalsIgnoreCase(computerProducer.getProducerName());
    
    boolean compProdExists = getAllCimputerProducers().map(list -> list.stream()
                                                                       .filter(cpPredicate)
                                                                       .findFirst()))
                                                      .isPresent();
    

    【讨论】:

      猜你喜欢
      • 2018-01-12
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-07
      • 2013-08-18
      相关资源
      最近更新 更多