使用可能返回transform
的函数Optional
使用番石榴null
的最佳(即最紧凑/可读)方式是什么? (因此,在这种情况下,我们应该得到Optional.absent()
,而不是NPE。)
奖金问题:如果变换器函数返回NPE
,那么以番石榴方式存在一个优势,即抛出null
? (而不是像Java 8 Optional.absent()
那样将其转换为Optional
。或者它只是设计的缺点?
根据documentation of Guava Optional.transform:
与java.util.Optional的比较:此方法类似于Java 8的
Optional.map
,除非函数返回null
。在这种情况下 方法抛出异常,而Java 8方法返回Optional.absent()
。
以下功能对两个示例都是通用的:
public String methodThatMighReturnNull(boolean returnNull, Integer input) {
return returnNull ? null : String.valueOf(input);
}
使用 Java 8 ,这不会抛出NPE,但会返回空的Optional
:
Optional<Integer> input = Optional.of(42);
Optional<String> result = input.map(new Function<Integer, String>() {
public String apply(Integer input) {
return methodThatMighReturnNull(true, input);
}
});
以下与 Guava 相似的代码会引发NPE:
Optional<Integer> input = Optional.of(42);
Optional<String> result = input.transform(new Function<Integer, String>() {
public String apply(Integer input) {
return methodThatMighReturnNull(true, input);
}
});
我已经找到/考虑了一些替代方案,但是,如下所述,所有问题都存在问题:
将返回值包装到Optional
。问题:太麻烦,难以阅读;
Optional<Integer> input = Optional.of(42);
Optional<String> result = input.transform(new Function<Integer, Optional<String>>() {
public Optional<String> apply(Integer input) {
return fromNullable(methodThatMighReturnNull(true, input));
}
}).get();
选中if/else
,使用ifPresent
。问题:有点杀死了Optional
。 (我们可以使用引用并检查null
而不是。)
Optional<Integer> input = Optional.of(42);
Optional<String> result;
if (input.isPresent()) {
result = fromNullable(methodThatMighReturnNull(true, input.get()));
} else {
result = Optional.absent();
}
只需应用该功能,并将其包装在fromNullable
中。 (正如GitHub所示,似乎已经出现了相同的问题。)问题:这与原始示例略有不同。在这种情况下,methodThatMighReturnNull
最终可能会收到null
,而在原始情况下,这是不可能的。
Optional<Integer> input = Optional.of(42);
Optional<String> result;
result = fromNullable(new Function<Integer, String>() {
public String apply(Integer input) {
return methodThatMighReturnNull(true, input);
}
}.apply(input.orNull()));
答案 0 :(得分:3)
除了您在问题中列出的替代方案外,还有两种可能性:
如果您使用的是Java 8或更高版本,从Guava 21.0开始,您将拥有Optional.toJavaUtil()
实例方法,该方法将您的Guava Optional
实例转换为java.util.Optional
实例,以及Optional.fromJavaUtil
静态方法,它从Optional
个实例创建一个Guava java.util.Optional
实例。
你可以使用它们让java.util.Optional
在你的Optional.map
方法中使用一个函数来调用你的方法,应用它自己的语义(如果函数返回{它不会抛出NullPointerException
{ {1}},但改为空null
。然后,如果您需要,请通过java.util.Optional
方法将此映射的java.util.Optional
转换回番石榴Optional
。
以下是显示此方法的代码:
Optional.fromJavaUtil
如果您还没有使用Java 8或更高版本(或者如果您不喜欢以前的方法),我会选择第二种替代方案。为此,我将使用您需要的语义实现Optional<Integer> input = Optional.of(42);
java.util.Optional<String> temp = input.toJavaUtil()
.map(i -> methodThatMighReturnNull(true, i));
Optional<String> result = Optional.fromJavaUtil(temp);
方法:
transformNullSafe
用法:
public static <T, R> Optional<R> transformNullSafe(
Optional<T> optional,
Function<T, R> function) {
if (optional.isPresent()) {
return Optional.fromNullable(function.apply(optional.get()));
} else {
return Optional.absent();
}
}