java - 空字符串的 Optional 实现

原文 标签 java string optional java-9

关于 Optional 的最好的事情之一是它保存了对 null 的所有样板检查。长链中的值:

Optional.ofNullable(myService.getSomething())
    .map(secondService::fetch)
    .map(thirdService::fetchAgain)
    // And so forth...

在任何时候,如果 map,Optional 将跳到“空”轨道上。返回 null .

如果可以对字符串做类似的事情而不是检查它们的 String::isEmpty,那就太好了。每次:
Optional.ofNullable(entity.getName())
    .filter(String::isEmpty)
    .map(Utils::performSomeOperation)
    .filter(String::isEmpty)
    .or(service::getMostCommonName)
    .filter(String::isEmpty)
    .orElse("Bob");

像这样的东西:
OptionalString.ofEmptyable(entity.getName())
    .map(Utils::performSomeOperation)
    .or(service::getMostCommonName)
    .orElse("Bob");

Optional 中的关键逻辑发生在 ofNullable当它调用 value == null 的检查时.从理论上讲,您可以在其中应用任何类型的逻辑:
MagicalOptionalString(StringUtils::isNotBlank).ofEmptyable(entity.getName())
    .map(Utils::performSomeOperation)
    .or(service::getMostCommonName)
    .orElse("Bob");

但是,Optional 是最终的,阻止了扩展此行为的任何直接方式。那么是否已经有一个现有的、健壮的实现呢?

最佳答案

尝试一些事情来解决您的目标,并意识到我会赞同 VGR 的想法,因为与使用现有方法相比,实现这样的用例需要做很多额外的工作。

然而,在花了一些时间查看实现后,我可以添加的细节很少 -

作为实用程序,您可以实现一个静态实现来验证 nullisEmpty字符串输入的条件并返回 Optional因此。代码可能看起来像 -

private static Optional<String> ofEmptyable(String string) {
    return isNullOrEmpty(string) ? Optional.empty() : Optional.of(string);
}

private static boolean isNullOrEmpty(String target) {
    return target == null || target.isEmpty();
}

这可以取代 ofNullable 的用法。它专门检查 null (Optional 的主要目的)。

由于您的问题陈述中的期望是实际处理每个方法的情况( map/or/orElse )调用作为 optional ,一种类似于 OptionalInt 的方法可能是实现自定义 OptionalString作为 -
public final class OptionalString {

    private static final OptionalString EMPTY = new OptionalString();

    private final boolean isPresent;
    private final String value;

    private OptionalString() {
        this.isPresent = false;
        this.value = "";
    }

    private static OptionalString empty() {
        return EMPTY;
    }

    private boolean isPresent() {
        return isPresent;
    }

    private OptionalString(String value) {
        this.isPresent = true;
        this.value = value;
    }

    public static OptionalString of(String value) {
        return value == null || value.isEmpty() ? OptionalString.empty() : new OptionalString(value);
    }

    public OptionalString map(Function<? super String, ? extends String> mapper) {
        return !isPresent() ? OptionalString.empty() : OptionalString.of(mapper.apply(this.value));
    }

    public OptionalString or(Supplier<String> supplier) {
        return isPresent() ? this : OptionalString.of(supplier.get());
    }

    String orElse(String other) {
        return isPresent ? value : other;
    }

    public String getAsString() {
        return Optional.of(value).orElseThrow(() -> new NoSuchElementException("No value present"));
    }
}

可以通过以下方式为您的用例进一步实现 -
String customImpl = OptionalString.of(entity.getName())
            .map(OptionalStringTest::trimWhiteSpaces) // OptionalStringTest is my test class name where 'trimWhiteSpaces' operation on String resides
            .or(service::getMostCommonName)
            .orElse("learning");
System.out.println(String.format("custom implementation - %s", customImpl));

在哪里
private static String trimWhiteSpaces(String x) {
    return x.trim();
}

备注 - 老实说,我找不到没有 OptionalString 背后的理由JDK 中的预先类(我之所以这么说是因为我怀疑它背后肯定有一个想法),我相信它只是我的范围半径要小得多,我希望有人可信详情在这里。恕我直言,使用 Optional<String> 似乎几乎所有您想要的东西都在那里这让我们回到循环的开始。

关于java - 空字符串的 Optional 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51771324/

相关文章:

java - 为什么不能在JavaDoc中使用<abbr>标记?

java - Java正则表达式删除csv中不需要的双引号

java - 嵌套格式的Java String格式未显示实际输出

swift - 在字符串中创建NSRange时崩溃

java - 在Optional中使用assertJ声明值

java - Camel junit测试带有bean组件的http组件

java - 在AsyncTask中运行CountDownTimer会引发java.lang.RuntimeException-Looper.prepare()

fortran - 如何为假定的形状数组使用 optional 属性

java - (Spring Boot)Optional <>类可以像List <>类吗?

java - 如何使用TestNG框架和Apache POI使用Java通过WebDriver在Excel中写入数据