如何使用 Java Optional 转换复杂的 if 条件

How to use Java Optional to convert a complex if condition

考虑以下 class

Class RequestBodyResource {
    private RequestVariable1 att1;
    private String att2;
    private String att3;
}

我有一个方法应该 return 在 2 个条件下为 false

基本上 "at least one" 或 "at most one"

代码与

相同
public boolean validateExactlyOneRequiredRequestParam(RequestBodyResource request) {

    //The below 3 conditions are to test that only one request is present
    if(StringUtils.isNotEmpty(request.getAtt3()) && null != request.getAtt1()) {
        return false;
    }
    if(StringUtils.isNotEmpty(request.getAtt2()) && null != request.getAtt1()) {
        return false;
    }
    if(StringUtils.isNotEmpty(request.getAtt3()) && StringUtils.isNotEmpty(request.getAtt2())) {
        return false;
    }

    //The below condition is to test that at least one request is present
    if(StringUtils.isEmpty(request.getAtt3()) && null == request.getAtt1() && StringUtils.isEmpty(request.getAtt2())) {
        return false;
    }
    return true;
}

如何使用Java 8 可选以使此代码更易于编写和阅读?

这里不需要 Optional。如果您只需要检查 至少一个 这些属性是否存在,您可以简单地将其检查为:

public boolean validateAtLeastOneRequiredRequestParam(RequestBodyResource request) {
    return request.getAtt1() != null 
            || !StringUtils.isEmpty(request.getAtt3()) 
            || !StringUtils.isEmpty(request.getAtt2());
}

编辑 1:对于 正好一个 检查,不是很好但比你当前的解决方案更具可读性(恕我直言):

public boolean validateExactlyOneRequiredRequestParam(RequestBodyResource request) {
    long countPresentAttribute = Stream.of(request.getAtt2(), request.getAtt3())
            .filter(StringUtils::isNotEmpty)
            .count() + 
            Stream.of(request.getAtt1()).filter(Objects::nonNull).count();
    return countPresentAttribute == 1;
}

编辑 2:使用 Optional 并摆脱对 StringUtils 的外部依赖,您可以这样做:

public boolean validateExactlyOneRequiredRequestParam(RequestBodyResource request) {
    long countPresentAttribute = Stream.of(
                Optional.ofNullable(request.getAtt1()),
                Optional.ofNullable(request.getAtt2()).filter(String::isEmpty),
                Optional.ofNullable(request.getAtt3()).filter(String::isEmpty))
            .filter(Optional::isPresent)
            .count();
    return countPresentAttribute == 1;
}

为什么不只数数?

int count = 0;
if(request.getAtt1() !=null) {
    count++;
}
if(StringUtils.isNotEmpty(request.getAtt2())) {
    count++;
}
if(StringUtils.isNotEmpty(request.getAtt3())) {
    count++;
}

return count == 1;

版本Optional(请勿使用,添加只是为了好玩)。

    return Optional.ofNullable(request.getAtt1()).map(ignore -> 1).orElse(0)
            + Optional.ofNullable(request.getAtt2()).map(ignore -> 1).orElse(0)
            + Optional.ofNullable(request.getAtt3()).map(ignore -> 1).orElse(0) 
           == 1;

也缺少对空字符串的检查。