简体   繁体   English

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

[英]How to use Java Optional to convert a complex if condition

Consider the following class 考虑以下课程

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

I have a method that should return false in 2 conditions 我有一种方法应在2种情况下返回false

  • If all the 3 attributes of the RequestBodyResource Object is null/empty 如果RequestBodyResource对象的所有3个属性为null / empty
  • If more than one attribute is not null 如果多个属性不为null

Basically "at least one" OR "at most one" 基本上是“至少一个”或“最多一个”

The code for the same is as 相同的代码是

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

How to use Java 8 Optional to make this code much easier to write and read? 如何使用Java 8 Optional使此代码更易于编写和阅读?

Why not just count? 为什么不算数呢?

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

return count == 1;

Version with Optional (do not use, it is added just for fun). 带有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;

Also it lack of check of empty strings. 也缺乏对空字符串的检查。

There is no need for an Optional here as such. 这样就不需要“ Optional了。 If you just need to check if at least one of those attributes are present, you could simply check it as: 如果仅需要检查是否至少存在这些属性之一 ,则可以将其检查为:

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

Edit 1 : For an exactly one check, not so good yet more readable(IMHO) than your current solution would be: 编辑1只需一张支票,还不如您当前的解决方案更好的可读性(IMHO):

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

Edit 2 : Using Optional and getting rid of an external dependency on StringUtils , you could do it as : 编辑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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM