optional用法

java8的改进中一个非常有用的就是optional,一句话概括,optional允许使用一个不确定是否为null的对象并且在对象为null的时候采取一系列的应对措施而不必抛出nullpointerException。

这项改进对于经常面对空指针异常的程序是个福音,因为按照以往的方式,要避免空指针异常,就必需进行null判断,如if(obj==null),另一种方式就是抛出异常并处理,然而这两种方式的语言表达能力并不好,复杂的场合可读性太差,所以使用optional可以解决这个问题。

public class Gen {
	//创封装一个为空的Optional<User>对象
	public Optional<User> user = Optional.empty();
	//封装一个Optional<User>,如果提供的User为null,则返回一个空的Optional<User>
        public Optional<User> user = Optional.ofNullable(new User());
	public void exe() {
		//get从Optional<User>去除user对象,如果对象为空,则抛出NoSuchElementEception
		user.get();
		
		//get相当于不判断user是否为null直接调用,为null则照旧抛出nullpointerException
		user.get().setId(10);
		user.get().setEmail("123");
		
		//of将一个对象封装为optional对象,如果对象为null,抛出NoSuchElementEception
		Optional.of(new User());
		
		//isPresent相当于if(user==null)
		System.out.println(user.isPresent());
		
		//ifPresent相当于if(user!=null)
		//			System.out.println(user.getId());
		//		else
		//			doNothing
		user.ifPresent((user)->System.out.println(user.getId()));
		
		//map和上面类似,但是必须使用对象本身的函数
		System.out.println(user.map((user)->user.getId()));
		
		//orElse通常跟map搭配,不通过则返回默认值
		System.out.println(user.map((user)->user.getId()).orElse(100));
		
		//orElseGet跟orElse类似,不通过返回一个Supplier<T>签名的函数
		Supplier<Integer> s= ()->new Integer(12);
		user.map((user)->user.getId()).orElseGet(s);
		
		//orElseThrow则是返回一个Supplier<Throwable>签名的函数
		Supplier<NumberFormatException> n = ()->new NumberFormatException();
		user.map((user)->user.getId()).orElseThrow(n);		
		
	}
	
	public static void main(String[] args) throws Exception {
		new Gen().exe();
	}
	
}

我们增加一个方法,用于返回Gen中的一个Optional对象

public Optional<User> getUser() {
		return user;
	}

如果我们希望输出一个Gen对象中的User对象的email,第一时间想到的是如下做法:

Optional<Gen> gen = Optional.ofNullable(new Gen());
		String email = gen.map(Gen::getUser).map(User::getEmail).orElse("noemail");//类型检查不通过
		System.out.println(email);

但是出现了类型错误,因为map方法跟stream类似,返回的是一个流,只不过是只有一个对象的流,并且这个流是嵌套的,也就是说第一个map返回的是一个Optional<Optional<User>>的对象流,对他进行getEmail操作显然是不支持的,这个时候使用flapmap:

String email = gen.flatMap(Gen::getUser).map(User::getEmail).orElse("noemail");

flatmap跟stream的类似,将嵌套的流扁平化为单一的流,从而解这种引用链。

比flatmap更进一步处理的有filter,例:

{
		user.get().setEmail("hello");//初始化一下属性
	}
gen.flatMap(Gen::getUser).filter((u)->u.getEmail().equals("hello"));

那么当user不为null且email为hello是,返回其optional对象,否则返回空的optional对象。

另外,optional对象作为属性,该属性是不能被序列化的,它没有实现序列化接口。



  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值