使用 Optional 简化许多 if 检查

Simplify many if checks with Optional

if (reg[0] != null && reg[0].trim().length() > 0) {
   orderData.setCity(reg[0]);
}
if (reg[1] != null && reg[1].trim().length() > 0) {
   orderData.setCountry(reg[1]);
}
if (reg[2] != null && reg[2].trim().length() > 0) {
   orderData.setObjectType(reg[2]);
}
if (reg[3] != null && reg[3].trim().length() > 0) {
   orderData.setChannel(reg[3]);
}

我可以使用 Optional 或其他 Java 8 个功能来简化它吗?

如果你真的要在这里寻找涉及 Optional 的实现,我在评论中建议的方法可以实现到 return 一个

private Optional<String> validInput(String input) {
    return Optional.ofNullable(input)
                   .filter(in -> in.trim().length() > 0);
}

那么这个可以用作

validInput(reg[0]).ifPresent(city -> orderData.setCity(city));
validInput(reg[1]).ifPresent(country -> orderData.setCountry(country));
... and the likes

Optional 将是错误的工具。

改为利用 StringUtils.isNotBlank

if (StringUtils.isNotBlank(reg[0])) {
   orderData.setCity(reg[0]);
}

您仍然需要写出每个值,因为它们映射到不同的字段,但这将清理它并允许您使用更传统的方法来检查空白字符串。

可选的可能不会在这里帮助你。

首先想到的是哨兵值。在这里,您清楚地表明您认为,从语义上讲,reg[0] 为 null 等同于 reg[0] 为空字符串(甚至是其中只有空格的字符串)。这应该是非凡的。 null 不是 'nothing' 或 'empty' 的替代。 null 应该是 'There is no value' 的替代品。最好的方法是找到生成 reg[0] 的地方,并确保在此处设置正确的语义(空字符串)。那么这段代码可以简单地是:if (!reg[0].isEmpty()) orderData.setCity(reg[0]); - 如此简洁。

当然,这并不总是可能的。例如,如果 reg 是从一个库或其他根本不受您控制的代码的管道中下来的,或者它是由 JSON 解组器创建的对象。

在那种情况下,我通常会建议创建一个明确的步骤来将 'not clean' 的对象(即使在语义上应该是空字符串也有空值)转换为干净的对象。

如果这不可行或不可能,那么,使用 'unclean' 对象永远不会特别漂亮,风格明智。辅助方法会有很大帮助,这里:

normalizeThenSetIfNonBlank(reg[0], orderData::setCity);
normalizeThenSetIfNonBlank(reg[1], orderData::setCountry);

private void normalizeThenSetIfNonBlank(String in, Consumer<String> target) {
    if (in == null) return;
    in = in.trim();
    if (in.isEmpty()) return;
    target.accept(in);
}
Optional.ofNullable(reg[0]).filter(val -> val.trim().length() > 0).ifPresent(orderData::setCity);
Optional.ofNullable(reg[1]).filter(val -> val.trim().length() > 0).ifPresent(orderData::setCountry);
Optional.ofNullable(reg[2]).filter(val -> val.trim().length() > 0).ifPresent(orderData::setObjectType);
Optional.ofNullable(reg[3]).filter(val -> val.trim().length() > 0).ifPresent(orderData::setChannel);