简介:Optional类是jdk1.8开始为我们提供的一个处理null的类。


代码实例说明:

声明:下面只示例介绍jdk1.8里Optional的用法,对于更高版本jdk里对Optional的进一步优化(如果有的话),
            这里不作介绍。

  • public T get()如果 Optional中存在值,则返回值,否则抛出 NoSuchElementException。

/*** .get()方法 : 如果 Optional中存在值,则返回值,否则抛出 NoSuchElementException** @author JustryDeng* @date 2019/7/15 20:49*/
@Test(expected = NoSuchElementException.class)
public void testFour() {Optional<?> optional = Optional.empty();optional.get();
}
  • public static <T> Optional<T> of(T value):获得持有value的Optional实例。

/*** .of(instance)方法 : 获得持有instance的Optional实例** 注:instance不能为null** @author JustryDeng* @date 2019/7/15 20:49*/
@Test
public void testOne() {Staff staff = Staff.builder().name("员工9527").age(123).staffNo("NO.1").build();Optional<Staff> optional = Optional.of(staff);Assert.assertEquals(optional.get(), staff);
}
  • public static <T> Optional<T> ofNullable(T value):获得持有value的Optional实例。

/*** .ofNullable(instance)方法 : 获得持有instance的Optional实例** 注:instance可以为null,为null时,获得的就是Optional.empty()** @author JustryDeng* @date 2019/7/15 20:49*/
@Test(expected = NoSuchElementException.class)
public void testTwo() {Optional<Staff> optional = Optional.ofNullable(null);// 当optional不持有值的时候,调用 optional.get()方法会抛出NoSuchElementException// 注:Optional.empty()方法获得的Optional实例,就是不持有值的Optional实例optional.get();
}
  • public boolean isPresent():判断optional持有的值是否为null(即:判断Optional是否持有值)。

/*** .isPresent()方法 : 判断optional持有的值是否为null(即:判断Optional是否持有值)。* 官方的话是 : 如果存在值,则返回 true ,否则为 false 。** @author JustryDeng* @date 2019/7/15 20:49*/
@Test
public void testThree() {Staff staff = Staff.builder().name("员工9527").age(123).staffNo("NO.1").build();// 持有值时(即:Optional<T>中,T不为null时)Optional<Staff> optionalOne = Optional.ofNullable(staff);Assert.assertTrue(optionalOne.isPresent());// 不持有值时Optional<Staff> optionalTwo = Optional.ofNullable(null);Assert.assertFalse(optionalTwo.isPresent());
}
  • public void ifPresent(Consumer<? super T> consumer):如果存在值,则使用该值调用指定的消费者,否则不执行任何操作。

class  MyConsumer implements Consumer<Staff>{@Overridepublic void accept(Staff staff) {System.out.println("重新了accept(T t)方法 -> " + staff);}
}/*** .ifPresent()方法 : 如果存在值,则使用该值调用指定的消费者,否则不执行任何操作。** @author JustryDeng* @date 2019/7/15 21:06*/
@Test
public void testFive() {Staff staff = Staff.builder().name("员工9527").age(123).staffNo("NO.1").build();Optional<Staff> optional = Optional.ofNullable(staff);optional.ifPresent(new MyConsumer());// 此处我们可以不需要显示的实现Consumer接口,而是直接使用lombda表达式来进行优化,如:// optional.ifPresent(s -> System.out.println("重新了accept(T t)方法 -> " + s));Optional<Staff> emptyOptional = Optional.empty();emptyOptional.ifPresent(k -> System.out.println("如果emptyOptional不持有值,那么是不会输出这句话的。"));
}
  • public Optional<T> filter(Predicate<? super T> predicate) : 如果一个值存在,并且该值给定的谓词相匹配时(即:filter(Predicate<? super T> predicate)里的,predicate判定结果为true时),返回一个 Optional描述的值,否则返回一个空的 Optional。

class  MyPredicate implements Predicate<Staff> {@Overridepublic boolean test(Staff staff) {boolean result = staff != null && staff.getAge() > 100;log.info(" MyPredicate.test result is -> {}", result);return result;}
}/*** .filter()方法 : 如果一个值存在,并且该值给定的谓词相匹配时(即:filter(Predicate<? super T> predicate)里的,*                predicate判定结果为true时),返回一个 Optional描述的值,否则返回一个空的 Optional 。** @author JustryDeng* @date 2019/7/15 21:06*/
@Test
public void testSix() {Staff staff = Staff.builder().name("员工9527").age(123).staffNo("NO.1").build();Optional<Staff> optionalOne = Optional.ofNullable(staff);// 匹配Predicate,那么会返回一个 Optional描述的值Optional<Staff> newOptionalOne = optionalOne.filter(new MyPredicate());// 此时newOptionalOne.isPresent()结果应该为trueAssert.assertTrue(newOptionalOne.isPresent());Optional<Staff> optionalTwo = Optional.ofNullable(null);// 不匹配Predicate,那么会返回一个不持有值的Optional实例(即:optional持有的是null)Optional<Staff> newOptionalTwo = optionalTwo.filter((s) -> s != null && s.getAge() > 1000);// 此时newOptionalOne.isPresent()结果应该为falseAssert.assertFalse(newOptionalTwo.isPresent());
}
  • public<U> Optional<U> map(Function<? super T, ? extends U> mapper):Optional的泛型(即:持有值 数据类型)转换。

class  MyFunction implements Function<String, Staff> {/*** 将String转换为Staff*/@Overridepublic Staff apply(String s) {return Staff.builder().name(s).build();}
}/*** .map()方法 : Optional的泛型(即:持有值 数据类型)转换** 注:如Optional<A>.map(Function<? super A, ? extends B> function)后会得到Optional<B>,其*    中function的apply方法中定义有从A转换到B的规则** 注:会应用function转换的前提是,Optional<A>持有值;** 注:如果Optional<A>没持有值,或者Optional<A>持有值,但经过function转换后的Optional<B>不持有值的话,那么*    会返回一个一个空的(即:不持有值的)Optional** @author JustryDeng* @date 2019/7/15 21:06*/
@Test
public void testSeven() {Optional<String> optionalOne = Optional.of("蚂蚁牙黑");// 将字符串Optional<String>转换为Optional<Staff>,即:将【蚂蚁牙黑】转换为StaffOptional<Staff> newOptionalOne = optionalOne.map(new MyFunction());Assert.assertEquals("蚂蚁牙黑", newOptionalOne.orElse(Staff.builder().build()).getName());
}

注:如Optional<A>.map(Function<? super A, ? extends B> function)后会得到Optional<B>,
       其中function的apply方法中定义有从A转换到B的规则。

注:会应用function转换的前提是,Optional<A>持有值。

注:如果Optional<A>没持有值,或者Optional<A>持有值,但经过function转换后的Optional<B>
       不持有值的话,那么会返回一个一个空的(即:不持有值的)Optional。

  • public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper):Optional泛型(即:持有值 数据类型)转换。

class  MyFunctionTwo implements Function<String, Optional<Staff>> {/*** 将String转换为Optional<Staff>*/@Overridepublic Optional<Staff> apply(String s) {return Optional.of(Staff.builder().name(s).build());}
}/*** .flatMap()方法 : Optional泛型(即:持有值 数据类型)转换** 注:如Optional<A>.map(Function<? super A, ? extends B> function)后会得到Optional<B>,其*    中function的apply方法中定义有从A转换到B的规则** 注:会应用function转换的前提是,Optional<A>持有值;** 注:如果Optional<A>没持有值,或者Optional<A>持有值,但经过function转换后的Optional<B>不持有值的话,那么*    会返回一个一个空的(即:不持有值的)Optional** @author JustryDeng* @date 2019/7/15 21:06*/
@Test
public void testEight() {Optional<String> optionalOne = Optional.of("蚂蚁牙黑");// 将String转换为Optional<Staff>,即:将【蚂蚁牙黑】转换为StaffOptional<Staff> newOptionalOne = optionalOne.flatMap(new MyFunctionTwo());Assert.assertEquals("蚂蚁牙黑", newOptionalOne.orElse(Staff.builder().build()).getName());
}

注:如Optional<A>.map(Function<? super A, ? extends B> function)后会得到Optional<B>,其
       中function的apply方法中定义有从A转换到B的规则。

注:会应用function转换的前提是,Optional<A>持有值。

注:如果Optional<A>没持有值,或者Optional<A>持有值,但经过function转换后的Optional<B>不
       持有值的话,那么会返回一个一个空的(即:不持有值的)Optional。

  • public T orElse(T other):返回值如果存在,则返回该值;否则返回 other。

/*** public T orElse(T other) 返回值如果存在,则返回该值;否则返回 other。** @author JustryDeng* @date 2019/7/16 9:44*/
@Test
public void testNine() {Staff defaultStaff = Staff.builder().name("默认姓名").build();Staff staff = Staff.builder().name("邓二洋").build();Optional<Staff> optionalOne = Optional.of(staff);// 若optionalOne持有值,则返回值;若不持有值(相当于持有的值为null),则返回defaultStaffStaff s1 = optionalOne.orElse(defaultStaff);Assert.assertEquals("邓二洋", s1.getName());Optional<Staff> optionalTwo = Optional.ofNullable(null);// 若optionalTwo持有值,则返回值;若不持有值(相当于持有的值为null),则返回defaultStaffStaff s2 = optionalTwo.orElse(defaultStaff);Assert.assertEquals("默认姓名", s2.getName());
}
  • public T orElseGet(Supplier<? extends T> other):若optional持有值,则返回值;若不持有值(相当于持有的值为null),则调用other并返回该调用的结果。

class MySupplier implements Supplier<Staff> {@Overridepublic Staff get() {return Staff.builder().name("李四").build();}
}
/*** public T orElseGet(Supplier<? extends T> other)* 若optional持有值,则返回值;若不持有值(相当于持有的值为null),则调用other并返回该调用的结果。** 提示:可使用lombda进行优化** @author JustryDeng* @date 2019/7/16 9:44*/
@Test
public void testTen() {Staff staff = Staff.builder().name("邓二洋").build();Optional<Staff> optionalOne = Optional.of(staff);// 若optionalOne持有值,则返回值;若不持有值(相当于持有的值为null),则调用Supplier.get并返回该调用的结果Staff s1 = optionalOne.orElseGet(new MySupplier());Assert.assertEquals("邓二洋", s1.getName());Optional<Staff> optionalTwo = Optional.ofNullable(null);// 若optionalTwo持有值,则返回值;若不持有值(相当于持有的值为null),则调用Supplier.get并返回该调用的结果Staff s2 = optionalTwo.orElseGet(new MySupplier());Assert.assertEquals("李四", s2.getName());
}
  • public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X:返回包含的值(如果存在),否则抛出由提供的供应商创建的异常。

class MySupplierTwo implements Supplier<RuntimeException> {@Overridepublic RuntimeException get() {return null;}
}/*** public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)* throws X extends Throwable* 返回包含的值(如果存在),否则抛出由提供的供应商创建的异常。** 提示:可使用lombda进行优化** @author JustryDeng* @date 2019/7/16 9:59*/
@Test(expected = RuntimeException.class)
public void testEleven() {Staff staff = Staff.builder().name("邓二洋").build();Optional<Staff> optionalOne = Optional.of(staff);// 若optionalOne持有值,则返回值;若不持有值(相当于持有的值为null),则抛出由提供的供应商创建的异常。Staff s1 = optionalOne.orElseThrow(new MySupplierTwo());Assert.assertEquals("邓二洋", s1.getName());Optional<Staff> optionalTwo = Optional.ofNullable(null);// 若optionalTwo持有值,则返回值;若不持有值(相当于持有的值为null),则抛出由提供的供应商创建的异常。Staff s2 = optionalTwo.orElseThrow(new MySupplierTwo());
}
  • public boolean equals(Object obj):Optional重写了equals方法,会比较Optional持有对象的值。

/*** Optional重写了equals方法,会比较Optional持有对象的值*/
@Test
public void testTwelve() {Staff staffOne = Staff.builder().name("邓二洋").age(25).build();Staff staffTwo = Staff.builder().name("邓二洋").age(25).build();Staff staffThree = Staff.builder().name("JustryDeng").age(25).build();// 第一个OptionalOptional<Staff> optionalOne = Optional.of(staffOne);// 第二个OptionalOptional<Staff> optionalTwo = Optional.of(staffTwo);// 第三个OptionalOptional<Staff> optionalThree = Optional.of(staffThree);// 第四个OptionalOptional<Staff> optionalFour = Optional.ofNullable(null);// 第五个OptionalOptional<Staff> optionalFive = Optional.ofNullable(null);// trueboolean resultOne = optionalOne.equals(optionalTwo);Assert.assertTrue(resultOne);// falseboolean resultTwo = optionalOne.equals(optionalThree);Assert.assertFalse(resultTwo);// true(若两个Optional都不持有对象,那么这两个Optional进行equals的结果为true)boolean resultThree = optionalFour.equals(optionalFive);Assert.assertTrue(resultThree);// falseboolean resultFour = optionalOne.equals(optionalFour);Assert.assertFalse(resultFour);
}
  • public int hashCode():返回当前值的哈希码值(如果有的话),如果没有值,则返回0(零)。

/*** Optional.hashCode* 返回当前值的哈希码值(如果有的话),如果没有值,则返回0(零)。*/
@Test
public void testThirteen() {Staff staffOne = Staff.builder().name("邓二洋").age(25).build();Staff staffTwo = Staff.builder().name("邓二洋").age(25).build();Staff staffThree = Staff.builder().name("JustryDeng").age(25).build();// 第一个OptionalOptional<Staff> optionalOne = Optional.of(staffOne);// 第二个OptionalOptional<Staff> optionalTwo = Optional.of(staffTwo);// 第三个OptionalOptional<Staff> optionalThree = Optional.of(staffThree);// 第四个OptionalOptional<Staff> optionalFour = Optional.ofNullable(null);int resultOne = optionalOne.hashCode();log.info(" resultOne is -> 【{}】!", resultOne);int resultTwo = optionalTwo.hashCode();log.info(" resultTwo is -> 【{}】!", resultTwo);// 求Optional对象的hashCode,实际上求的是Optional持有的对象的hashCodeAssert.assertEquals(resultOne, resultTwo);int resultThree = optionalThree.hashCode();Assert.assertNotEquals(resultOne, resultThree);int resultFour = optionalFour.hashCode();// 若Optional不持有值,那么hashCode值为0Assert.assertEquals(0, resultFour);
}
  • public String toString():返回此可选的非空字符串表示,适用于调试。

/*** Optional.toString* 返回此可选的非空字符串表示,适用于调试*/
@Test
public void testFourteen() {Staff staffOne = Staff.builder().name("邓二洋").age(25).build();Optional<Staff> optionalOne = Optional.of(staffOne);Staff staffTwo = Staff.builder().name("JustryDeng").age(25).build();Optional<Staff> optionalTwo = Optional.of(staffTwo);Optional<Staff> optionalThree = Optional.ofNullable(null);// Optional[T.toString]log.info(" optionalOne is -> 【{}】!", optionalOne);// Optional[T.toString]log.info(" optionalTwo is -> 【{}】!", optionalTwo);// 若不持有值,那么tiString结果为 Optional.emptylog.info(" optionalThree is -> 【{}】!", optionalThree);
}

提示一:更多细节,可详见JDK API文档。

提示二:本文只是示例的jdk1.8的Optional新特性,jdk1.9仍然对Optional有进一步优化,但本文这里并未示例。

^_^ 如有不当之处,欢迎指正

^_^ 参考文档
              《jdk api 1.8_google.CHM》

^_^ 测试代码托管链接
               https://github.com/JustryDeng…Jdk8Feature

^_^ 本文已经被收录进《程序员成长笔记(五)》,笔者JustryDeng

【jdk1.8特性】之Optional相关推荐

  1. 【Optional类】JDK1.8新特性之Optional类的使用

    这篇文章,主要介绍JDK1.8新特性之Optional类的使用. 目录 一.Optional类 1.1.Optional类介绍 1.2.Optional属性和方法 (1)value属性 (2)私有构造 ...

  2. JDK8新特性之Optional

    转载自 JDK8新特性之Optional Optional是什么 java.util.Optional Jdk8提供 Optional,一个可以包含null值的容器对象,可以用来代替xx != nul ...

  3. 【java8新特性】——Optional详解(三)

    一.简介 Optional类是Java8为了解决null值判断问题,借鉴google guava类库的Optional类而引入的一个同名Optional类,使用Optional类可以避免显式的null ...

  4. Java 8新特性:Optional类

    Java 8新特性:Optional类 在上一篇介绍Stream流式数据处理的文章中提到了Optional类,这是Java 8新增的一个类,用以解决程序中常见的NullPointerException ...

  5. 【小家java】java8新特性之---Optional的使用,避免空指针,代替三目运算符

    相关阅读 [小家java]java5新特性(简述十大新特性) 重要一跃 [小家java]java6新特性(简述十大新特性) 鸡肋升级 [小家java]java7新特性(简述八大新特性) 不温不火 [小 ...

  6. jdk1.8新特性(四)——Optional

    在我们的开发中,NullPointerException可谓是随时随处可见,为了避免空指针异常,我们常常需要进行一 些防御式的检查,所以在代码中常常可见if(obj != null) 这样的判断.JD ...

  7. optional判断是否为空_乐字节Java8核心特性之Optional

    小伙伴们,上次小乐给大家详细介绍了Java8核心特性的Stream(流),点击可以回顾哦. 乐字节:乐字节Java8核心特性实战-Stream流​zhuanlan.zhihu.com Optional ...

  8. Java 8 新特性,Optional介绍 | 春松客服

    目录 缘起 Optional类 Optional对象构造方法 提取Optional对象的值 使用orElse()方法获取值 使用filter()方法过滤 示例程序 注意事项 使用场景 orElseGe ...

  9. JDK1.8特性之StringJoiner

    StringBuilder.StringBuffer.String这三个的区别,很多文章都有在说. 这边也给大家做一个简要的概述 一:String.StringBuilder.StringBuffer ...

最新文章

  1. RH系列linux上编译android2.3(gingerbread)
  2. java使用ireport生成报表_JasperReport(3)——Java简单使用IReport生成的文件建立报表...
  3. 建设公司的技术+企业客户的沟通=极致运行的网站
  4. mtk6589显示子系统笔记(一)
  5. win10安装tesserocr配置 Python使用tesserocr识别字母数字验证码
  6. 无限极分类中递归查找一个树结构
  7. 如何设置背景图(前端开发)
  8. spark计算操作整理
  9. 多核CPU上python多线程并行的一个假象(转)
  10. Python-Flask实现基金自选网站
  11. VC++ 的 CImageList 绘制背景透明的位图
  12. Redis集群原理详解
  13. 计算机模拟比赛,关于参加2017年中小学计算机模拟城市设计比赛的通知
  14. 直线分割平面的公式_直线分割平面-jiangwen127-ChinaUnix博客
  15. Linux efi分区被删除了,恢复删掉的 MSR 和 EFI 分区
  16. php替换word字符串,word怎么用符号替换字符
  17. 图像的区域选取(matlib)
  18. 如何查看支付宝商户ID(支付宝pid)?
  19. 操作系统实验三:主存空间的分配与回收
  20. 和我一起写lua - 确认操作系统

热门文章

  1. flink sql读取kafka-入门级
  2. 利用matlab求系统的单位阶跃响应,基于Matlab6_5的归一化二阶系统单位阶跃响应的模拟演示...
  3. VMWare 卡顿优化详解
  4. Java随笔记 - 内核缓冲区与进程缓冲区
  5. wsl2 安装 Centos8
  6. JAVA输出一个3行4列数组_输入一个3行4列的数组,先以3行4列的格式输出该数组
  7. 如何逼自己玩命学习,这几款超奶思的学习APP,让你爱上学习!
  8. mysql时间戳转换大日期 2038 以上 2099
  9. python语音验证码识别_基于Python的手机语音验证码api调用代码实例
  10. python语音验证码识别_python语音验证码接口_python语音接口_python语音验证码_语音验证码代码示例_互亿无线...