Optional
Optional并不是提供功能, 而是提供一种null处理的规范,大家都用的话可能代码阅读起来容易一点? 源码很简单
ofNullable(
和 of(
和 empty()
构造器是private的, 有3个获取实例的静态方法
ofNullable(
和 of(
和 empty()
Optional.ofNullable(指定类实例);
//可接受null, 但null在get()仍然会抛异常Optional.of(指定类实例);
// null则抛异常, return new Optional<>(Objects.requireNonNull(value)); 直接调用Object的requireNonNull方法Optional.empty(指定类实例);
// 返回强制转换的 private static final Optional> EMPTY = new Optional<>(null);isPresent()
和 isEmpty()
isPresent()
和 isEmpty()
isEmpty()
源码return value == null;isPresent()
源码return value != null;is
开头,还有个以 if
开头的ifPresent(
方法可用拉姆达在有值时才执行get()
和 orElse
和 orElseGet
和 orElseThrow
乘2get()
和 orElse
和 orElseGet
和 orElseThrow
两个
get()
null则抛异常 和 orElseThrow()
一样orElse(null替代品)
null则返回替代品orElseGet(()=>{return null替代品;})
或 orElseGet(()=>null替代品)
null则返回替代品, 功能和orElse
一样, 写法不同orElseThrow()
null则抛异常 和 get() 一样orElseThrow(()->new Exception("自定义异常"));
// 取值, 值空则抛自定义的异常; public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
public T orElseThrow() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
get() 和 orElseThrow() 原理完全相同, onElseThrow()是Jdk10定义的, get()是8
ifPresent
和 ifPresentOrElse
ifPresent
和 ifPresentOrElse
ifPresent(值->{有值时执行的代码})
ifPresentOrElse(值->{有值时执行的代码} , new Thread(()->{无值时执行的代码}))
ifPresentOrElse(...
是java9新增的方法, 个人觉得不错, 明确了有值时做什么,值空时做什么.
下面是ifPresent
和 ifPresentOrElse
的源码对比, 来自java17
public void ifPresent(Consumer<? super T> action) {
if (value != null) {
action.accept(value);
}
}
/**
* If a value is present, performs the given action with the value,
* otherwise performs the given empty-based action.
*
* @param action the action to be performed, if a value is present
* @param emptyAction the empty-based action to be performed, if no value is
* present
* @throws NullPointerException if a value is present and the given action
* is {@code null}, or no value is present and the given empty-based
* action is {@code null}.
* @since 9
*/
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
if (value != null) {
action.accept(value);
} else {
emptyAction.run();
}
}
filter
, map
, flatMap
, or
filter(v->条件)
或 filter(v->{return 新v;}
//有值且真返自己, null值或假返empty();map(v->新v)
或 filter(v->{return 新v;}
//有值返新值新Optional, null值返empty(); 参数和flatMap不一样, 逻辑一样flatMapp(v->Optional.of("新值新Optional")))
//有值返新值新Optional, null值返empty(); 参数和map不一样. 逻辑一样or(()->Optional.of("新Optional包装的null替代品"))
//有值返自己, null值返新Optional包装的null替代品; 来自java9ifPresentOrElse
和 or
和 stream
ifPresentOrElse
和 or
上面已经讲过
stream
就是调用Stream
的发方法, 参考Stream
public Stream<T> stream() {
if (!isPresent()) {
return Stream.empty();
} else {
return Stream.of(value);
}
}
import java.util.Optional;
import static java.lang.System.out;
public class T2402200637 {
public static void main(String[] arguments){
try {
pln("hello你好");
pln("");
pln(null);
}catch(Exception e) {e.printStackTrace();}
}
static void pln(Object o) throws Exception{
hr();hr();hr();
out.println("原始值="+o);
Optional<Object>op = null;
hr("ofNullable(o)");
op = Optional.ofNullable(o); //可接受null, 但null在get()仍然会抛异常
out.println("isEmpty()="+op.isEmpty()); // isEmpty() 源码return value == null;
out.println("isPresent="+op.isPresent()); // isPresent()源码return value != null;
try {
Object o2 = op.get(); // 取值, 值空则抛throw new NoSuchElementException("No value present"); 自jdk8. jdk10定义的orElseThrow()和它源码一模一样
out.println(o2);
}catch(Exception e) {e.printStackTrace(out); out.println("get()抛的"); }
out.println(op.orElse("空指针默认值")); // orElse( 源码public T orElse(T other) {return value != null ? value : other;}
out.println(op.orElseGet(()->{return "用Supplier实现的空指针默认值";}));
out.println(op.orElseGet(()->"也可以省略return和分号大括号写成这样的:用Supplier实现的空指针默认值"));
try {
Object o2 = op.orElseThrow(); // 取值, 值空则抛throw new NoSuchElementException("No value present"); 和get()一模一样
out.println(o2);
}catch(Exception e) {e.printStackTrace(out); out.println("orElseThrow()抛的"); }
try {
Object o2 = op.orElseThrow(()->new Exception("自定义异常")); // 取值, 值空则抛自定义的异常;
out.println(o2);
}catch(Exception e) {e.printStackTrace(out); out.println("orElseThrow()抛的"); }
op.ifPresent(v->{out.println("因为值不为null,所以执行了 ifPresent(Consumer super T> action) 值为:"+v);}); //如果不null就执行拉姆达
op.ifPresentOrElse(
v->{out.println("因为值不为null,所以ifPresentOrElse(执行了第一个参数的拉姆达,如同ifPresent方法,值为:"+v);}
,
new Thread(()->{out.println("看到这句说明值null, 如果null值则ifPresentOrElse执行第二个参数的Runnable, 因为新起线程,所以不会阻塞. "); })
);
out.println("op.filter(v->true) 的结果:" + op.filter(v->true)); //有值且真返自己, null值或假返empty();
out.println("op.filter(v->false)的结果:" + op.filter(v->false)); //有值且真返自己, null值或假返empty();
out.println("op.map(v->\"新值\")的结果:" + op.map(v->"新值")); //有值返新值新Optional, null值返empty(); 参数和flatMap不一样, 逻辑一样
out.println("op.flatMap(v->Optional.of(\"新值新Optional\")的结果:" + op.flatMap(v->Optional.of("新值新Optional"))); //有值返新值新Optional, null值返empty(); 参数和map不一样. 逻辑一样
out.println("op.or(()->Optional.of(\"新Optional包装的null替代品\")的结果:" + op.or(()->Optional.of("新Optional包装的null替代品"))); //有值返自己, null值返新Optional包装的null替代品;
hr("of(o)");
try {
op = Optional.of(o); // null则抛异常, return new Optional<>(Objects.requireNonNull(value));
}catch(Exception e) {e.printStackTrace(out); out.println("of(实例)抛的, 因为实例为空...再of"); op=Optional.of("因为上次of(null),这里再of(保证不空)"); }
out.println("isEmpty()="+op.isEmpty()); // isEmpty() 源码return value == null;
out.println("isPresent="+op.isPresent()); // isPresent()源码return value != null;
try {
Object o2 = op.get(); // 取值, 值空则抛throw new NoSuchElementException("No value present");
out.println(o2);
}catch(Exception e) {e.printStackTrace(out); out.println("get()抛的"); }
out.println(op.orElse("空指针默认值")); // orElse( 源码public T orElse(T other) {return value != null ? value : other;}
out.println(op.orElseGet(()->{return "用Supplier实现的空指针默认值";}));
out.println(op.orElseGet(()->"也可以省略return和分号大括号写成这样的:用Supplier实现的空指针默认值"));
try {
Object o2 = op.orElseThrow(); // 取值, 值空则抛throw new NoSuchElementException("No value present");
out.println(o2);
}catch(Exception e) {e.printStackTrace(out); out.println("orElseThrow()抛的"); }
try {
Object o2 = op.orElseThrow(()->new Exception("自定义异常")); // 取值, 值空则抛自定义的异常;
out.println(o2);
}catch(Exception e) {e.printStackTrace(out); out.println("orElseThrow()抛的"); }
op.ifPresent(v->{out.println("因为值不为null,所以执行了 ifPresent(Consumer super T> action) 值为:"+v);}); //如果不null就执行拉姆达
op.ifPresentOrElse(
v->{out.println("因为值不为null,所以ifPresentOrElse(执行了第一个参数的拉姆达,如同ifPresent方法,值为:"+v);}
,
new Thread(()->{out.println("看到这句说明值null, 如果null值则ifPresentOrElse执行第二个参数的Runnable, 因为新起线程,所以不会阻塞. "); })
);
out.println("op.filter(v->true) 的结果:" + op.filter(v->true)); //有值且真返自己, null值或假返empty();
out.println("op.filter(v->false)的结果:" + op.filter(v->false)); //有值且真返自己, null值或假返empty();
out.println("op.map(v->\"新值\")的结果:" + op.map(v->"新值")); //有值返新值新Optional, null值返empty(); 参数和flatMap不一样, 逻辑一样
out.println("op.flatMap(v->\"新值新Optional\")的结果:" + op.flatMap(v->Optional.of("新值新Optional"))); //有值返新值新Optional, null值返empty(); 参数和map不一样. 逻辑一样
out.println("op.or(()->Optional.of(\"新Optional包装的null替代品\")的结果:" + op.or(()->Optional.of("新Optional包装的null替代品"))); //有值返自己, null值返新Optional包装的null替代品;
hr("empty()");
op = Optional.empty(); // 返回强制转换的 private static final Optional> EMPTY = new Optional<>(null);
out.println("isEmpty()="+op.isEmpty()); // isEmpty() 源码return value == null;
out.println("isPresent="+op.isPresent()); // isPresent()源码return value != null;
try {
Object o2 = op.get(); // 取值, 值空则抛throw new NoSuchElementException("No value present");
out.println(o2);
}catch(Exception e) {e.printStackTrace(out); out.println("get()抛的"); }
out.println(op.orElse("空指针默认值")); // orElse( 源码public T orElse(T other) {return value != null ? value : other;}
out.println(op.orElseGet(()->{return "用Supplier实现的空指针默认值";}));
out.println(op.orElseGet(()->"也可以省略return和分号大括号写成这样的:用Supplier实现的空指针默认值"));
try {
Object o2 = op.orElseThrow(); // 取值, 值空则抛throw new NoSuchElementException("No value present");
out.println(o2);
}catch(Exception e) {e.printStackTrace(out); out.println("orElseThrow()抛的"); }
try {
Object o2 = op.orElseThrow(()->new Exception("自定义异常")); // 取值, 值空则抛自定义的异常;
out.println(o2);
}catch(Exception e) {e.printStackTrace(out); out.println("orElseThrow()抛的"); }
op.ifPresent(v->{out.println("因为值不为null,所以执行了 ifPresent(Consumer super T> action) 值为:"+v);}); //如果不null就执行拉姆达
op.ifPresentOrElse(
v->{out.println("因为值不为null,所以ifPresentOrElse(执行了第一个参数的拉姆达,如同ifPresent方法,值为:"+v);}
,
new Thread(()->{out.println("看到这句说明值null, 如果null值则ifPresentOrElse执行第二个参数的Runnable, 因为新起线程,所以不会阻塞. "); })
);
out.println("op.filter(v->true) 的结果:" + op.filter(v->true)); //有值且真返自己, null值或假返empty();
out.println("op.filter(v->false)的结果:" + op.filter(v->false)); //有值且真返自己, null值或假返empty();
out.println("op.map(v->\"新值\")的结果:" + op.map(v->"新值")); //有值返新值新Optional, null值返empty(); 参数和flatMap不一样, 逻辑一样
out.println("op.flatMap(v->\"新值新Optional\")的结果:" + op.flatMap(v->Optional.of("新值新Optional"))); //有值返新值新Optional, null值返empty(); 参数和map不一样. 逻辑一样
out.println("op.or(()->Optional.of(\"新Optional包装的null替代品\")的结果:" + op.or(()->Optional.of("新Optional包装的null替代品"))); //有值返自己, null值返新Optional包装的null替代品;
}
static void hr(String str) { for(int c=0;c<100;c++)out.append("-"); out.append(str).println(); }
static void hr() {hr("");}
}
Optional
是 Java 8 引入的一个容器对象,它可能包含也可能不包含非 null
的值。Optional
的主要目的是提供一个更好的替代方案,以避免 NullPointerException
和改进代码的可读性。
以下是 Optional
的一些基本用法:
使用 Optional.of()
、Optional.empty()
和 Optional.ofNullable()
方法创建 Optional 对象。
Optional<String> optional1 = Optional.of("value"); // 非null值
Optional<String> optional2 = Optional.empty(); // 空Optional
String possiblyNull = getPossiblyNullValue();
Optional<String> optional3 = Optional.ofNullable(possiblyNull); // 可能是null或非null
使用 isPresent()
方法检查 Optional 对象是否包含值。
if (optional.isPresent()) {
// 值存在
} else {
// 值不存在
}
使用 get()
方法获取 Optional 对象的值。如果值不存在,此方法将抛出 NoSuchElementException
。因此,在调用 get()
之前,最好先检查值是否存在。
if (optional.isPresent()) {
String value = optional.get();
}
使用 orElse()
方法获取 Optional 对象的值,如果值不存在,则返回一个默认值。
String value = optional.orElse("default");
使用 ifPresent()
方法对 Optional 对象的值执行操作,如果值存在。
optional.ifPresent(value -> System.out.println(value));
使用 map()
方法对 Optional 对象的值进行转换。如果值不存在,则不进行任何操作。
Optional<Integer> lengthOptional = optional.map(String::length);
使用 orElseGet()
方法在 Optional 对象为空时计算并返回一个值。这对于需要执行耗时操作以获取默认值的情况非常有用。
String value = optional.orElseGet(() -> expensiveDefaultValueComputation());
使用 orElseThrow()
方法在 Optional 对象为空时抛出一个异常。你可以提供一个 Supplier
来创建并抛出所需的异常。
String value = optional.orElseThrow(() -> new IllegalStateException("Value not present"));
使用 filter()
方法根据特定条件过滤 Optional 对象的值。如果值存在且满足条件,返回包含该值的 Optional;否则返回空 Optional。
Optional<String> filteredOptional = optional.filter(value -> "desiredValue".equals(value));
你可以将多个 Optional
操作链接在一起,以创建更复杂的逻辑。例如:
String result = optional
.filter(value -> "desiredValue".equals(value))
.map(String::toUpperCase)
.orElse("DEFAULT");
Java Optional是Java 8引入的一个类,用于解决空指针异常的问题。它可以包含一个非空值,也可以为空。下面是Java Optional的常用用法:
Optional<String> optional = Optional.of("value"); // 创建一个包含非空值的Optional对象
Optional<String> emptyOptional = Optional.empty(); // 创建一个空的Optional对象
Optional<String> nullableOptional = Optional.ofNullable(null); // 创建一个可能为空的Optional对象
optional.isPresent(); // 判断Optional对象是否包含非空值,返回true或false
optional.get(); // 获取Optional对象中的非空值,如果Optional对象为空,则抛出NoSuchElementException异常
optional.orElse("default"); // 获取Optional对象中的非空值,如果Optional对象为空,则返回默认值
optional.orElseGet(() -> "default"); // 获取Optional对象中的非空值,如果Optional对象为空,则通过Supplier函数式接口返回默认值
optional.orElseThrow(() -> new RuntimeException("Value not present")); // 获取Optional对象中的非空值,如果Optional对象为空,则抛出指定的异常
optional.ifPresent(value -> System.out.println(value)); // 如果Optional对象包含非空值,则执行指定的操作
optional.ifPresentOrElse(
value -> System.out.println(value),
() -> System.out.println("Value not present")); // 如果Optional对象包含非空值,则执行指定的操作,否则执行默认的操作
optional.filter(value -> value.length() > 5); // 如果Optional对象包含非空值,并且满足指定的条件,则返回包含该值的Optional对象,否则返回空的Optional对象
optional.map(value -> value.toUpperCase()); // 如果Optional对象包含非空值,则对该值进行映射操作,并返回包含映射结果的Optional对象,否则返回空的Optional对象
optional.flatMap(value -> Optional.of(value.toUpperCase())); // 如果Optional对象包含非空值,则对该值进行映射操作,并返回映射结果,否则返回空的Optional对象