使用 Optional 避免 NPE

Using Optional to avoid NPE

我试图避免检查 (if ... != null)try{...}catch(NullPointerException e) {...}

让我们举个例子来理解我的问题:

我有一个 class Park 包含 List<Car> 我有一个 class Car 包含一个 Motor object 我有一个 class Motor 包含一个 Name String

我想 return 我公园的第一个字符串电机名称 class :

我想避免:

if (park != null) {
    if (park.getCars() != null) {
        for (Car car : park.getCars() {
              if (car.getMotor() != null) {
                  return car.getMotor().getName();

我在想这样的事情:

Optional.ofNullable(park).map(Park::getCars).ifPresent(cars -> {
    return cars.stream().map(Car::getMotor).map(Motor::getName).findFirst().orElse(null);
});

但它无法编译。有什么想法吗??

Optional.ifPresent() 具有 void 作为 return 类型,因此您不能 return 函数中的结果。您可以使用 Optional.stream()Stream.flatMap() 代替:

return Optional.ofNullable(park) // Optional<Park>
        .map(Park::getCars).stream() // Stream<List<Car>>
        .flatMap(List::stream) // Stream<Car>
        .map(Car::getMotor) // Stream<Motor>
        .filter(Objects::nonNull) // Stream<Motor>
        .map(Motor::getName) // Stream<String>
        .findFirst() // Optional<String>
        .orElse(null);

或者(如果您不能使用 Optional.stream())您可以使用 Optional.flatMap() 和您已有的代码:

return Optional.ofNullable(park) // Optional<Park>
        .map(Park::getCars) // Optional<List<Car>>
        .flatMap(cars -> cars.stream() // Stream<Car>
                .map(Car::getMotor) // Stream<Motor>
                .filter(Objects::nonNull) // Stream<Motor>
                .map(Motor::getName) // Stream<String>
                .findFirst()) // Optional<String>
        .orElse(null);

假设你限制在java 8,你可以使用这个:

    public String findFirstMotorName(Park park) {
        return Optional.ofNullable(park)
            .map(Park::getCars)
            .map(
                cars -> cars.stream().map(Car::getMotor).map(Motor::getName).findFirst().orElse(null)
            )
            .orElse("No Motors Found");
    }

在以后的版本中,您还可以将 Optional 转换为 Stream,这样会更流畅一些。