Java 可选接口:可选对象链上的嵌套条件

Java Optional interface: Nested conditions on Optional object chain

我想再次编写此代码一个完整的 Optional 流畅的方法来做到这一点:

Optional<Reference> reference = this.referenceService.get(id);
if (!reference.isPresent()) {
    return Response.status(Status.NOT_FOUND).build();
}

EntityTag entityTag = this.eTag(reference.get());
ResponseBuilder responseBuilder = this.request.evaluatePreconditions(entityTag);

if (Objects.isNull(responseBuilder)) {
    responseBuilder = Response
        .ok()
        .entity(reference.get())
        .cacheControl(this.cacheControl)
        .tag(entityTag);
}

return responseBuilder.build();

到目前为止,我已经做到了:

return this.referenceService.get(id)
    .map(this::eTag)
    .map(this.request::evaluatePreconditions)
    .orElse(Response.status(Status.NOT_FOUND))
    .cacheControl(this.cacheControl)
    .tag(this.eTag(this.referenceService.get(id).get()))
    .build();

但是这段代码和之前的代码不一样。

我有两个条件要处理:

if (!reference.isPresent()) {
    return Response.status(Status.NOT_FOUND).build();
}

if (Objects.isNull(responseBuilder)) {

我不太明白如何解决这个问题。

有什么想法吗?

第一个条件if (!reference.isPresent()).orElse(Response.status(Status.NOT_FOUND))覆盖

覆盖第二个条件if (Objects.isNull(responseBuilder))this.request.evaluatePreconditions(entityTag) 的结果创建一个 Optional,然后从 orElseGet 到 return the ok builder

下面的代码是我脑补出来的,没有测试

this.referenceService
    .get(id)
    .map(this::eTag)
    .map(entityTag -> Optional.ofNullable(this.request.evaluatePreconditions(entityTag))
                                .orElseGet(() -> Response.ok()
                                                        .entity(entityTag)
                                                        .cacheControl(this.cacheControl)
                                                        .tag(entityTag)))
    .orElse(Response.status(Status.NOT_FOUND))
    .buld();

为了简化表达式,可以在方法中重构 Optional.ofNullable(...).orElseGet(...) 部分并调用该方法,而不是让所有内联

类似下面的内容

private ResponseBuilder getBuilderOrDefault(EntityTag entityTag) {
    return Optional.ofNullable(this.request.evaluatePreconditions(entityTag))
                   .orElseGet(() -> Response.ok()
                                            .entity(entityTag)
                                            .cacheControl(this.cacheControl)
                                            .tag(entityTag));
}

映射将变为

this.referenceService
    .get(id)
    .map(this::eTag)
    .map(this::getBuilderOrDefault)
    .orElse(Response.status(Status.NOT_FOUND))
    .buld();