Java可选返回值仅在存在时

时间:2018-04-09 09:41:41

标签: java lambda functional-programming optional

是否可以仅在方法中返回Optional值,但是如果它不仅仅是继续正常的方法流程。像这样:

public Message processMessage(Message message) {
        // ErrorMessage is subclass of Message; only returned if validator found some violations, otherwise empty optional
        Optional<ErrorMessage> error = validator.validate(message);

        if (error.isPresent()) return error.get();

        // returns different possible subclasses of Message
        return service.processMessage(message);
    }

有没有更漂亮的方法来写这个?

4 个答案:

答案 0 :(得分:1)

我只会选择Optional.orElseGet并在两者之间进行明确的演员:

public Message processMessage(final Message message) {
  return validator.validate(message)
    .map(Message.class::cast)
    .orElseGet(() -> service.processMessage(message));
}

答案 1 :(得分:1)

您的问题确实是返回类型不匹配。 orElseGet仅在供应商返回Optional类型的子类型时才有效。

要解决此问题,您可以先强制转换为父类型:

return error.<Message>map(m -> m).orElseGet(() -> service.processMessage(message));

或等效地:

return error.map(m -> (Message) m).orElseGet(() -> service.processMessage(message));

答案 2 :(得分:0)

我目前无法测试它,但它可能会给你一个想法,也许你可以实现类似下面的内容

return Optional.ofNullable(message)
.map(validator::validate)
.orElseGet(service::processMessage)

答案 3 :(得分:0)

查看该代码段,validate上的validator方法似乎没有正确的返回类型。考虑使用例如io.vavr.control.Eitherio.vavr.control.Validation monad。看一下validate的可能签名:

Either<SpecificError, ? extends Message> validate(Message message);

现在mapfold组合器可以像这样使用:

validator
    .validate(message)
    .map(message -> service.processMessage(message))
    .fold(error -> new ErrorMessage(error), success -> success); // the left function can be replaced by Function.identity()

获得Message