代码中给了很详细的测试和注释,很容易看懂,建议仔细看一遍。控制台输出再最下方。
Optional是个容器,类型为Optional
创建Optional可以用三种方法empty、of、ofNullable。
empty创建一个空的,of和ofNullable需要一个对象作为参数,放进Optional里面并返回,区别在于of里面不可以放进null,它会报错。可以通过ofNullable()可以接受空对象。
使用get提取出Optional里面的对象(为空时报错),用isPresent可以判断是否为空,返回值为boolean。
orElse不为空时返回自身,为空时返回设定的默认值,并用Optional包装。
例如:
int b=1;Optional\<int> a=Optional.of(b);
a.orElse(100) //返回a自身
若a包含了非空的int,则返回这个包含了int的Optional;若为空,则返回一个包含了100的Optional。
filter可以过滤掉不符合要求或者为空的对象,同样的符合的时候返回自身,不符合的时候返回一个空的Optional。
例如:
a.fliter(x->x==0)
若a里面不为空且存的对象的值为0(表达式返回true),返回a。否则返回空的Optional。
而map可以按你自己的爱好转换非空对象为其他任意类型对象,然后自动包装好并返回。
例如:
int b=100; Optional\<int> a=Optional.of(b);
a.map(x->String.valueOf(x)); //返回一个装着“100”的字符串的Optional
Optional强大之处在于很好地处理了null,不再需要一路判断null了。
如:
假设有一个对象a持有了b对象,b又持有了c,我们需要打印出c,如果不存在就打印默认值-1;
传统写法需要判断三次:a!=null, a.b!=null, a.b.c!=null
至少写三个if语句。
现在只需要把a装进Optional里,这里用A表示:
System.out.println(A.map(x->x.b).map(x->x.c).orElse(-1));
如果不希望有默认值:可以用
A.map(x->x.b).map(x->x.c).ifPresent(System.out::println);
实际上更常用的语句是:
MyClass b=new MyClass(10);
a.orElse(new MyClass(0)).get();
在java11里,建议用orElseThrow无参数版代替get
这里推荐先学习一下lambda表达式和Supplier、Consumer、Functional、Predicate四个函数式接口相关知识。
与上述函数对应关系分别为:
Consumer->ifPresent (注意是if不是is)
Functional->map
Predicate->fliter
Supplier->orElseGet
package com.crimson.master;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Random;
public class TestOptional
{
public static void main(String[] args)
{
//test creation 测试三种创建方法,of()可能会报异常。这里test 13都是空的Optional,
// 5因为异常没得到赋值,是null状态,是个空指针
Optional<TestOptional>
test1 = Optional.empty(),
test2 = Optional.of(new TestOptional(2)),
test3 = Optional.ofNullable(null),
test4 = Optional.ofNullable(new TestOptional(4)),
test5 = null;
try
{
test5 = Optional.of(null);
} catch (Exception e)
{
System.out.println("用of(null)创建test5时出现异常 " + e);
}
List<Optional<TestOptional>> list = Arrays.asList(test1, test3, test5);
//test using 测试提取信息 使用get(),而isPresent判断是否为空
System.out.println("开始提取信息");
System.out.println("test2:" + test2.get() + " test4:" + test4.get());
int count = -1;
System.out.println("调用get时捕获到异常!");
for (Optional<TestOptional> i : list)
{
try
{
count += 2;
System.out.println(i.get());
} catch (Exception e)
{
System.out.println("异常来自:test" + count + "异常为: " + e);
}
}
System.out.println("测试isPresent");
System.out.println("test1为:" + test1.isPresent() + " test2为:" + test2.isPresent());
//test orElse orElseThrow orElseGet三种orElse方法
// 三种方法仅当为空时才有效执行,不为空时返回原来的Optional
System.out.println("测试orElse方法,依次测试123,or统一为100的值");
System.out.println(test1.orElse(new TestOptional(100)));
System.out.println(test2.orElse(new TestOptional(100)));
System.out.println(test3.orElse(new TestOptional(100)));
System.out.println("测试orElseGet,这里提供随机数");
System.out.println(test3.orElseGet(() -> new TestOptional(new Random().nextInt())));
try
{
System.out.println("测试orElseThrow抛出异常");
System.out.println(test3.orElseThrow(
() -> {
return new Exception("test3正通过orElse抛出异常");
}));
} catch (Exception e)
{
System.out.println(e);
}
//test fliter 测试过滤器,不为空且断言为true才返回原来的Optional,否则返回空的
System.out.println("测试过滤器,测试124,判断是否a的值为1,等于返回自身,不等于返回空");
System.out.println(test1.filter(x -> x.getA() == 1));
System.out.println(test2.filter(x -> x.getA() == 1));
System.out.println(test4.filter(x -> x.getA() == 1));
//test ifPresent 如果不为空传给消费函数
System.out.println("测试ifPresent,不为空时打印自身,为空时不操作,测试23");
test2.ifPresent(x -> System.out.println(x));
test3.ifPresent(x -> System.out.println(x));
//测试映射方法 map 测试
System.out.println("测试映射,不为空时映射,测试2,映射成100倍的int,装在Optional");
System.out.println(test2.map(x -> x.getA() * 100).get());
}
private int a = 0;
public String toString()
{
return String.valueOf(a);
}
TestOptional(int a)
{
this.a = a;
}
public int getA()
{
return a;
}
public void setA(int a)
{
this.a = a;
}
}
这里是控制台的输出结果:
用of(null)创建test5时出现异常 java.lang.NullPointerException
开始提取信息
test2:2 test4:4
调用get时捕获到异常!
异常来自:test1异常为: java.util.NoSuchElementException: No value present
异常来自:test3异常为: java.util.NoSuchElementException: No value present
异常来自:test5异常为: java.lang.NullPointerException
测试isPresent
test1为:false test2为:true
测试orElse方法,依次测试123,or统一为100的值
100
2
100
测试orElseGet,这里提供随机数
-1610499459
测试orElseThrow抛出异常
java.lang.Exception: test3正通过orElse抛出异常
测试过滤器,测试124,判断是否a的值为1,等于返回自身,不等于返回空
Optional.empty
Optional.empty
Optional.empty
测试ifPresent,不为空时打印自身,为空时不操作,测试23
2
测试映射,不为空时映射,测试2,映射成100倍的int,装在Optional
200