Java 8 可选:ifPresent 返回对象或Else抛出异常

问题描述 投票:0回答:6

我正在尝试做这样的事情:

 private String getStringIfObjectIsPresent(Optional<Object> object){
        object.ifPresent(() ->{
            String result = "result";
            //some logic with result and return it
            return result;
        }).orElseThrow(MyCustomException::new);
    }

这是行不通的,因为 ifPresent 将 Consumer 函数接口作为参数,其中有 void accept(T t)。它不能返回任何值。还有其他办法吗?

java lambda option-type
6个回答
108
投票

实际上您正在搜索的是:Optional.map。您的代码将如下所示:

object.map(o -> "result" /* or your function */)
      .orElseThrow(MyCustomException::new);

如果可以的话,我宁愿省略通过

Optional
。最后,在这里使用
Optional
你什么也得不到。另一种稍微不同的变体:

public String getString(Object yourObject) {
  if (Objects.isNull(yourObject)) { // or use requireNonNull instead if NullPointerException suffices
     throw new MyCustomException();
  }
  String result = ...
  // your string mapping function
  return result;
}

如果您由于另一次调用而已经拥有

Optional
-对象,我仍然建议您使用
map
-方法,而不是
isPresent
等,原因只有一个,我发现它更具可读性(显然是一个主观决定;-))。


33
投票

这里有两个选项:

ifPresent
替换为
map
并使用
Function
代替
Consumer

private String getStringIfObjectIsPresent(Optional<Object> object) {
    return object
            .map(obj -> {
                String result = "result";
                //some logic with result and return it
                return result;
            })
            .orElseThrow(MyCustomException::new);
}

使用

isPresent

private String getStringIfObjectIsPresent(Optional<Object> object) {
    if (object.isPresent()) {
        String result = "result";
        //some logic with result and return it
        return result;
    } else {
        throw new MyCustomException();
    }
}

18
投票

请改用

map
功能。它转换可选值内的值。

像这样:

private String getStringIfObjectIsPresent(Optional<Object> object) {
    return object.map(() -> {
        String result = "result";
        //some logic with result and return it
        return result;
    }).orElseThrow(MyCustomException::new);
}

17
投票

我更喜欢在确保值可用后进行映射

private String getStringIfObjectIsPresent(Optional<Object> object) {
   Object ob = object.orElseThrow(MyCustomException::new);
    // do your mapping with ob
   String result = your-map-function(ob);
  return result;
}

或一个衬垫

private String getStringIfObjectIsPresent(Optional<Object> object) {
   return your-map-function(object.orElseThrow(MyCustomException::new));
}

1
投票

你举的例子不是一个好例子。可选值不应作为参数发送到另一个函数中。好的做法是始终将非空参数发送到函数中。这样我们就始终知道输入不会为空。这可以减少我们的代码不确定性。


0
投票

从 Java 9 开始,我们有了

ifPresentOrElse()
。不幸的是,第二个参数是
Runnable
而不是 exceptionSupplier。

我们可以添加一个辅助方法来让它变得漂亮。

    public <X extends Throwable> Runnable toThrow(Supplier<X> exceptionSupplier) throws X {
        throw exceptionSupplier.get();
    }

    // Pretty now
    opt.ifPresentOrElse(obj::setter, toThrow(IllegalStateException::new));

© www.soinside.com 2019 - 2024. All rights reserved.