重写一个方法来使用 Optional 而不改变这个方法之外的任何东西

Rewriting a method to use Optional without changing anything outside this method

我遇到过这段代码。

public AnimalResponse getAnimal(Specie specie) {
    AnimalEntity animal = speciesRepository.findBySpecie(specie).orElseThrow(
        () - > new ResourceNotFoundException(specie)
    ).getAnimal();

    if (animal == null) {
        throw new NoAnimalException();
    }

    return getAnimal(animal.getId());
}

getAnimal() 方法可能 return 为空,因此稍后在该对象上调用 getId() 会导致 NPE。因此使用了我想避免的空检查。

我想知道:如何重写此方法以使其使用 Optionals 并保持相同的功能?可行吗,会不会更干净?

我意识到这个方法充其量是令人困惑的,但我不想改变这个方法之外的任何东西,并且努力从 Optional 工作中做出任何事情。

如果我没理解错的话,你可以像这样用 Optional.ofNullable() 包装它:

public AnimalResponse getAnimal(Specie specie) {
    AnimalEntity animal = Optional.ofNullable(speciesRepository
            .findBySpecie(specie)
            .orElseThrow(() - >
                new ResourceNotFoundException(specie))
            .getAnimal())
        .orElseThrow(() - > new NoAnimalException());

    return getAnimal(animal.getId());
}

trdanv 的回答在不改变行为的情况下已经差不多了。

如果您能够将这两个例外合并为一个涵盖 Animal 为 null 或 species not being found 的例外,那么您就可以更加地道地使用 Optional

return speciesRepository.findBySpecie(specie)
    .map(Species::getAnimal)
    .map(AnimalEntity::getId)
    .map(this::getAnimal)
    .orElseThrow(() -> new AnotherException(specie));

基本上我的理想是我们将物种映射到动物然后我们抛出异常

AnimalEntity animal = speciesRepository.findBySpecie(specie)
        .map(spec -> spec.getAnimal())
        .orElseThrow(() -> new ResourceNotFoundException(specie));
return getAnimal(animal.getId());