可选ofNullable中的字符串值

时间:2019-01-23 15:37:52

标签: java java-8 optional

想象一个Optional.ofNullable支票分配给一个String

String result = Optional.ofNullable(class1)
                .map(Class1::getClass2)
                .map(Class2::getResult);

getResult返回String的地方。

虽然我知道它不能编译,但我可以通过添加toString().orElse("");进行排序来修复它。

就目前而言,错误是:

  

方法参考中的返回类型错误,无法转换java.lang.String   到

我了解添加orElse("")是因为这会将result分配给空的String

但是,如果一路上有toString(),那么添加null有什么好处?还是仅仅是为了使其能够编译?

3 个答案:

答案 0 :(得分:2)

map的返回类型为Optional <U>,因此,要获取真实值,应使用返回类型为orElse的{​​{1}}来调用。

如果T,则这是toString的实现:

Optional

因此,调用@Override public String toString() { return value != null ? String.format("Optional[%s]", value) : "Optional.empty"; } 永远不会获得真实值,而是包装到toString的值,而Optional将返回您提供的默认值。

让我们来看看区别:

orElse

输出:

Integer i = 4;
String s = Optional.ofNullable(i)
         .map(Objects::toString)
         .toString();
System.out.println(s);

使用Optional[4]

null

输出:

Integer i = null;
String s = Optional.ofNullable(i)
          .map(Objects::toString)
          .toString();
System.out.println(s);

使用Optional.empty 时:

orElse

输出:

Integer i = null;
String s = Optional.ofNullable(i)
        .map(Objects::toString)
        .orElse("None");
System.out.println(s);

因此您可以看到这些方法有不同的用途。

以及您评论的答案:

有没有办法在同一链中调用get()并同时调用orElse()?

None

输出:

Integer i = 10;
String s = Optional.ofNullable(i)
        .map(Objects::toString)
        .orElse("None");
System.out.println(s);

您不需要显式调用10 ,如果不是get,则将获取该值;

null

答案 1 :(得分:1)

如果您希望result为null,而途中某事返回null,则执行orElse(null)

String result = Optional.ofNullable(class1)
            .map(Class1::getClass2)
            .map(Class2::getResult).orElse(null);

答案 2 :(得分:1)

  

我了解添加orElse(“”),因为这会将结果分配为空   字符串。

这听起来不像您对我理解的那样,因为这不是正在发生的事情的好描述。 Optional.orElse执行以下操作:如果可选包含值,则返回该值。如果它不包含值,则返回您提供的任何参数。

从语义上讲,它等同于以下内容:

if (optional.ifPresent())
{
    return optional.get();
}
else
{
    return theArgument;
}

调用toString虽然可以满足编译器的要求,但不是。您正在将Optional对象本身转换为字符串,而不是从内部获取字符串!尽管您的字符串将被包含,但这仅是因为JDK开发人员决定如何实现toString。他们同样可能没有提供实现,而只剩下just the default behaviour

在日志记录之外,永远不应依赖在toString上调用Optional。从本质上讲,它只是调试信息。如果执行此操作,则还将打印有关Optional包装器的信息,这几乎肯定不是您想要的。

System.out.println(Optional.empty());   // Optional.empty
System.out.println(Optional.of("foo")); // Optional[foo]