【问题标题】:Using Optional to avoid NPE使用 Optional 避免 NPE
【发布时间】:2019-07-17 14:23:03
【问题描述】:

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

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

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

我想从我的 Park 类中返回第一个字符串电机名称:

我想避免:

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);
});

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

【问题讨论】:

  • 你为什么突然用ifPresent而不是map?

标签: java java-8 java-stream optional


【解决方案1】:

假设你仅限于 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,这会使事情变得更加流畅。

【讨论】:

    【解决方案2】:

    Optional.ifPresent() 有void 作为返回类型,所以你不能在函数中返回结果。您可以改用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);
    

    【讨论】:

    • 谢谢,看起来好多了。但我认为我不能在代码的第二行中的 Optional> 上使用 stream() ...需要检查
    • @AntonBoarf 再次检查,我添加了另一个使用Optional.flatMap() 的示例。
    • 感谢尝试过,但没有一个编译过。检查原因
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 2020-10-14
    • 2012-12-08
    • 2020-01-06
    • 2023-03-31
    相关资源
    最近更新 更多