Java Optional 使用技巧
最近发现有人在讨论 Optional
的出现很鸡肋,但我不这么认为。虽然Optional
不是那样的完美,但是也很优雅的解决了一些场景的 Null 指针问题。
使用技巧
-
永远不要让 Optional 也为 NULL
Optional 的出现就是为了解决空指针问题
class A {
// 成员变量不要使用 Optional
// private Optional<String> name;
// 或者初始化为 Optional.empty()
// private Optional<String> name = Optional.empty();
private String name;
public void print() {
// 在使用时用Optional
Optional.ofNullable(name).ifPresent(System.out::println);
}
}
-
无需判断空的链式调用
class Scratch {
public static void main(String[] args) {
A a = new A();
// b || c 都有可能为null
Optional.of(a)
.map(A::getB)
.map(B::getC)
.ifPresent(System.out::println);
}
}
class A {
private B b;
public B getB() {
return b;
}
}
class B {
private C c;
public C getC() {
return c;
}
}
class C {
}
-
过滤一些数据
class Scratch {
public static void main(String[] args) {
A a = new A();
Optional.of(a)
.map(A::getName)
// 过滤掉 name 为空掉数据
.filter(StringUtils::isNotEmpty)
.ifPresent(System.out::println);
}
}
class A {
private String name;
public String getName() {
return name;
}
}
-
取数据不为空
class Scratch {
public static void main(String[] args) {
A a = new A();
// 默认值
String name = Optional.of(a)
.map(A::getName)
.orElse("张三");
name = Optional.of(a)
.map(A::getName)
.orElseGet(String::new);
// 为空抛出异常
name = Optional.of(a)
.map(A::getName)
.orElseThrow(IllegalAccessError::new);
}
}
class A {
private String name;
public String getName() {
return name;
}
}
-
flatMap(不会再次包装 Optional)
class Scratch {
public static void main(String[] args) {
A a = new A();
String name = Optional.of(a)
.map(A::getNameList)
// findAny 会返回一个 Optional
.flatMap(e -> e.stream().filter("哆啦A梦"::equals).findAny())
.orElse("大熊");
}
}
class A {
private List<String> nameList;
public List<String> getNameList() {
return nameList;
}
}
感觉少了点什么
个人愚见 ifPresent
可以重载一个数据为空时调用的函数,下面是一个人希望加入的方法,无法运行
class Scratch {
public static void main(String[] args) {
A a = new A();
String name = Optional.of(a)
.map(A::getNameList)
.flatMap(e -> e.stream().filter("哆啦A梦"::equals).findAny())
.ifPresent(System.out::println, () -> {
// 这边可以在数据为空时调用
System.out.println("没有找到多啦A梦😭");
});
}
}
// 可惜无法继承 jdk Optional
class Optional<T> {
T value;
// 希望 jdk 加入这样的方法
public void ifPresent(Consumer<? super T> consumer, Runnable r) {
if (value != null)
consumer.accept(value);
else
r.run();
}
}
class A {
private List<String> nameList;
public List<String> getNameList() {
return nameList;
}
}