Optional用法(Java SE 8–Java SE 9)
原文:原文地址IntroductionOptional 是一个包含或着不包含一个非空值的容器对象。如果一个值存在,isPresent()将会返回true 并且 get() 将会返回所对应的值.其他的方法依赖于所包含的值是否出现,比如orElse(如果值不存在就返回一个默认值)并且ifPresent()(如果值存在就执行一个代码块)。ExamplesMap
原文:原文地址
Introduction
Optional 是一个包含或着不包含一个非空值的容器对象。如果一个值存在,isPresent()
将会返回true
并且 get()
将会返回所对应的值.
其他的方法依赖于所包含的值是否出现,比如orElse
(如果值不存在就返回一个默认值)并且ifPresent()
(如果值存在就执行一个代码块)。
Examples
Map
使用Optional
的map()
方法去处理可能为null
的值,而并不做显式的null
类型检查:
Syntax:
public <U> Optional<U> map(Function<? super T,? extends U> mapper)
代码示例:
String value = null;
return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "NONE"
String value = "something";
return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "SOMETHING"
Note that the map() and filter() operations are evaluated immediately, unlike their Stream counterparts which are only evaluated upon a terminal operation.
注意到map()
和 filter()
操作很快被evaluated , 不像他们的Stream counterparts 在出现终端操作的时候才被evaluated。(Stream中 如果没有出现终端操作流 前面的调用将不被考虑)
Null-safe chaining
因为 当它的mapping函数返回null
Optional.map()
就会返回一个空的Optional,你能够链式的调用map()
操作来作为空指针安全的一种解决方式。考虑下面的列子:
String value = foo.getBar().getBaz().toString();
getBar
, getBaz
, 和toString
可能潜在的抛出NullPointerException
接下来变换一种方式使用Optional来从toString()
中得到值 :
String value = Optional.ofNullable(foo)
.map(Foo::getBar)
.map(Bar::getBaz)
.map(Baz::toString)
.orElse("");
如果任何一个mapping函数返回null
结果都将返回一个空字符串。
Optional.ofNullable(foo)
.map(Foo::getBar)
.map(Bar::getBaz)
.map(Baz::toString)
.ifPresent(System.out::println);
这个例子仅仅在没有任何mapping函数返回null
的情况下打印该值。
Return default value if Optional is empty
不要使用Optional.get()
因为这可能抛出 NoSuchElementException
.。Optional.orElse(T)
和 Optional.orElseGet(Supplier<? extends T>)
方法提供了一个方法当Optional是空的时候提供一个默认值。
String value = "something";
return Optional.ofNullable(value).orElse("defaultValue");
// returns "something"
return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// returns "something" (never calls the getDefaultValue() method)
String value = null;
return Optional.ofNullable(value).orElse("defaultValue");
// returns "defaultValue"
return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// calls getDefaultValue() and returns its results
orElse
和 orElseGet
的关键不同之处在于当Optional为空后者才被调用同时返回的参数被提供给前者(ofNullable),前者是无论Optional是否为空都会被调用。orElse
因此应该被用于常量,并且永远不会提供基于任何排序计算的值。
Throw exception if there is no value edit share
使用Optional
方法的orElseThrow()
方法去得到所包含的值或着抛出一个异常,如果值从未被设置。 除了它允许任意的异常类型,这和调用get()
很相似 , 这个方法采用一个必须返回将要抛出异常的supplier。
在第一个示例中,方法简单的返回所包含的值:
Optional optional = Optional.of("something");
return optional.orElseThrow(IllegalArgumentException::new);
// returns "something" string
第二个样例中,方法抛出一个异常,因为值从未被set
Optional optional = Optional.empty();
return optional.orElseThrow(IllegalArgumentException::new);
// throws IllegalArgumentException
如果抛出异常的话你也可以使用lambda语法,message是必须的。
optional.orElseThrow(() -> new IllegalArgumentException("Illegal"));
Using Optional containers for primitive number types
OptionalDouble
, OptionalInt
和 OptionalLong
的工作就像Optional
,但是它们被专门的被设计为包装基本类型:
OptionalInt presentInt = OptionalInt.of(value);
OptionalInt absentInt = OptionalInt.empty();
因为数字类型都有一个值,所以没有专门的对于null的处理,空的containers 能够被检查:
presentInt.isPresent(); // Is true.
absentInt.isPresent(); // Is false.
类似的,shorthands 存在去补充对值的管理
// Prints the value since it is provided on creation.
presentInt.ifPresent(System.out::println);
// Gives the other value as the original Optional is empty.
int finalValue = absentInt.orElseGet(this::otherValue);
// Will throw a NoSuchElementException.
int nonexistentValue = absentInt.getAsInt();
Filter
filter()
被用来表示能够匹配你给定的条件的某些你想要的值。 把他想象成if (!somePredicate(x)) { x = null; }.
代码示例:
String value = null;
Optional.ofNullable(value) // nothing
.filter(x -> x.equals("cool string"))// this is never run since value is null
.isPresent(); // false
String value = "cool string";
Optional.ofNullable(value) // something
.filter(x -> x.equals("cool string"))// this is run and passes
.isPresent(); // true
String value = "hot string";
Optional.ofNullable(value) // something
.filter(x -> x.equals("cool string"))// this is run and fails
.isPresent(); // false
Lazily provide a default value using a Supplier
(使用Supplier懒惰的提供一个默认值)
正常的 orElse
方法需要一个Object
对象作为参数,所以你可能想知道为什么有一个选项来提供Supplier
Consider:
String value = "something";
return Optional.ofNullable(value)
.orElse(getValueThatIsHardToCalculate()); // returns "something"
它仍然会调用getValueThatIsHardToCalculate()
即使它的结果没有被使用,因为optional非空。
要避免这个“惩罚”,你要提供一个supplier:
String value = "something";
return Optional.ofNullable(value)
.orElseGet(() -> getValueThatIsHardToCalculate()); // returns "something"
这样 getValueThatIsHardToCalculate()
只有在Optional
为空的时候才会被调用。
Run code only if there is a value present
(当值存在的时候才运行代码)
Optional<String> optionalWithValue = Optional.of("foo");
optionalWithValue.ifPresent(System.out::println);//Prints "foo".
Optional<String> emptyOptional = Optional.empty();
emptyOptional.ifPresent(System.out::println);//Does nothing.
flatMap
flatMap
和map
很相似, 但是如果你链式的调用返回Optional
的方法,你可能更倾向于使用flatMap
,这样你最终不用使用嵌套的Optionals
Given the following classes:
class Foo {
Optional<Bar> getBar(){
return Optional.of(new Bar());
}
}
class Bar {
}
如果你使用map
, 你将得到嵌套的Optional<Optional<Bar>>
Optional<Optional<Bar>> nestedOptionalBar =
Optional.of(new Foo())
.map(Foo::getBar);
然而,当使用flatMap
,一个简单的Optional<Bar>
被返回
Optional<Bar> optionalBar =
Optional.of(new Foo())
.flatMap(Foo::getBar);
译者补充
假设你有一个会返回Optional<T>
的方法f, 并且目标类型T有一个会返回Optional<U>
的方法g。如果他们都是普通的方法,你可能会考虑调用s.f().g()
将他们组合起来。但是这种组合是行不通的。因为s.f()
方法返回的是Optional<T>
而不是T,但是我们可以调用:
Optional<U> = s.f().flatMap(T::g);
假设有一个Test
类包含一个计算平方根的静态方法和inverse(Double x)
方法
public class Test {
public static Optional<Double> squareRoot(Double x) {
return x < 0 ? Optional.empty() : Optional.of(Math.sqrt(x));
}
public static Optional<Double> inverse(Double x) {
return x == 0 ? Optional.empty() : Optional.of(1 / x);
}
//那么我们可以这样计算反转值的平方根:
public static void main(String[] args) {
Optional<Double> result = Optional.of(4.0).flatMap(Test::inverse).flatMap(Test::squareRoot);
result.ifPresent(System.out:: println);
}
}
如果inverse
和 squareRoot
有任何一个返回Optional.empty()
, 结果都返回空
Optional<Double> result = Optional.of(-4.0).flatMap(Test::inverse).flatMap(Test::squareRoot);
// return Optional.empty
更多推荐
所有评论(0)