Java基础之Optional类(JDK1.8新特性)

举报
码农飞哥 发表于 2021/05/29 13:16:43 2021/05/29
【摘要】 定义 Optional是一个容器,它可以保存类型T的值,或者仅仅保存null,Optional类主要是用来避免空指针异常(NPE),其提供的一系列的方法配合Lambda表达式可以让代码更加清晰,语义化,以及避免了空指针异常的问题,这里要注意是避免空指针异常,而不是避免返回null。 Optional方法的使用 empty 方法返回一个不包含值的Optional实例...

定义

Optional是一个容器,它可以保存类型T的值,或者仅仅保存null,Optional类主要是用来避免空指针异常(NPE),其提供的一系列的方法配合Lambda表达式可以让代码更加清晰,语义化,以及避免了空指针异常的问题,这里要注意是避免空指针异常,而不是避免返回null

Optional方法的使用

  1. empty 方法返回一个不包含值的Optional实例,注意不保证返回的empty是单例,不要用==比较。
public static<T> Optional<T> empty() 

  
 
  • 1
  1. of 方法返回一个Optional实例,传入的值必须是非空值,传入null会抛出空指针异常。
public static <T> Optional<T> of(T value) 

  
 
  • 1
  1. 返回一个Optional实例,如果传入值非空,则实例中包含非空值,如果传入null,返回不包含值的empty
 public static <T> Optional<T> ofNullable(T value)

  
 
  • 1
  1. isPresent 方法用来判断实例是否包含值,如果不包含非空值返回false,否则返回true
	public boolean isPresent();


  
 
  • 1
  • 2
  1. get方法,如果实例包含值则返回当前值,否则抛出NoSushElementException 异常.
	public T get();

  
 
  • 1

不推荐调用上面两个方法,因为容易写出如下代码,比原先判断if null的代码还要脏

 public static String getUserName1(User user) { Optional<User> user1 = Optional.ofNullable(user); if (!user1.isPresent()) { return "参数为空"; } return user1.get().getName(); }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

下面是用if-null

  public static String getUserName(User user) { if (user == null) { return "参数为空"; } return user.getName(); }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. ifPresent(Consumer consumer):如果option对象保存的值不是null,则调用consumer对象,否则不调用
		public void ifPresent(Consumer<? super T> consumer);

  
 
  • 1

代码示例:

	  Optional<Integer> optional1 = Optional.ofNullable(1); Optional<Object> optional2 = Optional.ofNullable(null); //如果不是null,调用Consumer optional1.ifPresent(t -> System.out.println("value is" + t));   //value is1 //如果是null,不调用Consumer optional2.ifPresent(t -> System.out.println("value is " + t)); 
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如上代码,输出结果是 第一条 语句输出value is1,第二条语句没有输出
7. filter方法如果值存在,并且这个值匹配给定的predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional

Optional<T> filter(Predicate<? super <T> predicate)


  
 
  • 1
  • 2

代码示例:

		Optional<Integer> optional1 = Optional.ofNullable(1); Optional<Object> optional2 = Optional.ofNullable(null); Optional<Integer> filter1 = optional1.filter(a -> a == null); Optional<Integer> filter2 = optional1.filter((a) -> a == 1); Optional<Object> filter3 = optional2.filter(a -> a == null); System.out.println(filter1.isPresent()); //false System.out.println(filter2.isPresent()); //true System.out.println(filter2.get().intValue() == 1); //true System.out.println(filter3.isPresent()); //false

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如上代码,演示了filter方法如何使用,输出结果如代码注释所示。
8. map(Function):对Optional中保存的值进行函数运算,并返回新的Optional(可以是任何类型)

	public<U> Optional<U> map(Function<? super T, ? extends U> mapper);

  
 
  • 1

代码示例:输出结果已经写在注释中。

	 Optional<Integer> optional1 = Optional.ofNullable(1); Optional<Object> optional2 = Optional.ofNullable(null);
		Optional<String> str1Optional = optional1.map(a -> "key" + a); Optional<String> str2Optional = optional2.map(a -> "key" + a); System.out.println(str1Optional.get()); //key1 System.out.println(str2Optional.isPresent()); //false

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. flatMap():功能与map()相似,差别在返回值不同,flatMap方法的mapping函数返回值可以是任何类型T,而map方法的mapping函数必须是Optional
	public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper);


  
 
  • 1
  • 2

代码示例:

		Optional<Integer> optional1 = Optional.ofNullable(1); Optional<Object> optional2 = Optional.ofNullable(null); Optional<Optional<String>> str11Optional = optional1.map(a -> Optional.of("key" + a)); Optional<String> str22Optional = optional1.flatMap(a -> Optional.of("key" + a)); System.out.println(str11Optional.get().get()); //key1 System.out.println(str22Optional.get()); //key1

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. orElse方法,如果optional对象保存的值不是null,则返回原来的值,否则返回value。
	public T orElse(T other);


  
 
  • 1
  • 2

代码示例:

 Optional<Integer> optional1 = Optional.ofNullable(1); Optional<Object> optional2 = Optional.ofNullable(null); System.out.println(optional1.orElse(1000) == 1); //true System.out.println((Integer) optional2.orElse(1000) == 1000);//true

  
 
  • 1
  • 2
  • 3
  • 4
  1. orElseGet(Supplier supplier):功能与orElse一样,只不过orElseGet参数是一个对象。
	public T orElseGet(Supplier<? extends T> other);


  
 
  • 1
  • 2

代码示例:

 Optional<Integer> optional1 = Optional.ofNullable(1); Optional<Object> optional2 = Optional.ofNullable(null); System.out.println(optional1.orElseGet(() -> 1000) == 1); //true System.out.println((Integer) optional2.orElseGet(() -> 1000) == 1000); //true


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  1. orElseThrow方法,值不存在则调用传入的Supplier参数,生成一个异常实例并抛出,这个方法通常与全局异常处理器一起使用,当参数或者其他情况获取不到值是,抛出自定义异常,由异常处理器处理成通用返回结果。
	public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier);


  
 
  • 1
  • 2

代码示例:

 optional1.orElseThrow(() -> { throw new IllegalStateException(); }); try { optional2.orElseThrow(() -> { throw new IllegalStateException(); }); } catch (IllegalStateException e) { e.printStackTrace(); }


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

实战参考

假设我们要解析一段json字符串,按照传统的if-null方式我们需要做如下处理:为了获取CUid的值,我们必须要判断三次。

 public static String getOrgUid(String orgResult) { if (StringUtils.isBlank(orgResult)) { return null; } JSONObject jsonObject = JSON.parseObject(orgResult); if (jsonObject == null) { return null; } if ("success".equals(jsonObject.getString("result"))) { return jsonObject.getString("CUid"); } return null; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

而运用了我们的Optional类之后,我们可以通过函数式变成来实现。

 public static String getNewUid(String orgResult) { String orElse = Optional.ofNullable(orgResult) .map(n -> JSONObject.parseObject(n)) .map(a -> { if ("success".equals(a.getString("result"))) { return a.getString("CUid"); } return null; }).orElse(null); return orElse; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

运用了函数式变成,我们只需要三段3段代码就能轻松的驾驭,代码简洁明了。

总结

本文主要介绍了Optional类的一些常用方法,以及其应用场景,其主要是为了规避空指针异常(NPE)。熟练的运用Optional类可以很大的简化我们的代码,使代码简洁明了。

参考

JDK8 Optional 应用场景与方式分析
Java 8 Optional 类
JDK8新特性:使用Optional

文章来源: feige.blog.csdn.net,作者:码农飞哥,版权归原作者所有,如需转载,请联系作者。

原文链接:feige.blog.csdn.net/article/details/104385258

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。