参考资料:https://www.baeldung.com/java-optional

    https://mp.weixin.qq.com/s/P2kb4fswb4MHfb0Vut_kZg

1. 描述

  Optional是java.util包中的一部分,所以要有相关的引用:

import java.util.Optional;

2. 创建Optional方法

2.1 empty,创建一个空的Optional

@Test
public void whenCreatesEmptyOptional_thenCorrect() {
Optional<String> empty = Optional.empty();
assertFalse(empty.isPresent());
}

2.2 of,创建Optional,使用of方法时,传入不能为null,否则会报NullPointerException异常:

@Test
public void givenNonNull_whenCreatesNonNullable_thenCorrect() {
String name = "baeldung";
Optional<String> opt = Optional.of(name);
assertTrue(opt.isPresent());
}

2.3 ofNullable,创建Optional,ofNullable方法是允许值为null的

@Test
public void givenNonNull_whenCreatesNullable_thenCorrect() {
String name = "baeldung";
Optional<String> opt = Optional.ofNullable(name);
assertTrue(optionalName.isPresent());
}

3. 判断Optional的值

3.1 isPrensent,判断Optional是否有值,返回boolean类型,上面几个创建例子都用了isPresent,源码:

public boolean isPresent() {
return value != null;

3.2 ifPrensent,如果Optional有值,执行后面函数

@Test
public void givenOptional_whenIfPresentWorks_thenCorrect() {
Optional<String> opt = Optional.of("baeldung");
opt.ifPresent(name -> System.out.println(name.length()));
}

  如果在Optional为null的情况下,直接使用ifPresent有可能会报NullPointerException,所以就有了下面几个函数。

3.3 orElse和orElseGet,返回Optional包裹的值,如果值为null,则返回函数内的默认值,这两个方法的区别在于orElse后面跟默认值对象,orElseGet跟的是表达式函数。

@Test
public void whenOrElseWorks_thenCorrect() {
String nullName = null;
String name = Optional.ofNullable(nullName).orElse("john");
assertEquals("john", name);
} @Test
public void whenOrElseGetWorks_thenCorrect() {
String nullName = null;
String name = Optional.ofNullable(nullName).orElseGet(() -> "john");
assertEquals("john", name);
}

3.4 orElseThrow,返回Optional包裹的值,如果值为null,则抛出异常

@Test(expected = IllegalArgumentException.class)
public void whenOrElseThrowWorks_thenCorrect() {
String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow(IllegalArgumentException::new);
}

3.5 get,返回Optional包裹的值,如果值为null,会抛出NoSuchElementException异常

@Test(expected = NoSuchElementException.class)
public void givenOptionalWithNull_whenGetThrowsException_thenCorrect() {
Optional<String> opt = Optional.ofNullable(null);
String name = opt.get();
}

4. Optional值的操作

4.1 map,将一个值转换成另一个值,下面的例子是返回字符串的长度,没有则返回默认值0

@Test
public void givenOptional_whenMapWorks_thenCorrect2() {
String name = "baeldung";
Optional<String> nameOptional = Optional.of(name);
int len = nameOptional.map(String::length).orElse(0);
assertEquals(8, len);
}

4.2 filter,用于过滤。接收一个函数式接口,当符合接口时,则返回一个Optional对象,否则返回一个空的Optional对象

@Test
public void whenOptionalFilterWorks_thenCorrect() {
Integer year = 2016;
Optional<Integer> yearOptional = Optional.of(year);
boolean is2016 = yearOptional.filter(y -> y == 2016).isPresent();
assertTrue(is2016);
boolean is2017 = yearOptional.filter(y -> y == 2017).isPresent();
assertFalse(is2017);
}

5. 与Lambda表达式结合使用,优化代码

5.1 条件为true就执行

优化前:

String person = "wo are you";
if(person != null){
System.out.println(person);
}

优化后:

Optional<String> optional = Optional.of("wo are you");
optional.ifPresent(System.out::println);

5.2 条件为true就返回,false返回默认值

优化前:

String person = "wo are you";
if(person != null){
System.out.println(person);
} else {
return DEFAULT_VALUE;
}

优化后:

Optional<String> optional = Optional.of("wo are you");
return optional.orElse(DEFAULT_VALUE);

5.3 条件为true就返回,false调用函数生成

优化前:

String person = "wo are you";
if(person != null){
System.out.println(person);
} else {
return createPerson();
}

优化后:

Optional<String> optional = Optional.of("wo are you");
return optional.orElseGet(t -> createPerson());

5.4 连环null检查

优化前:

Person person = new Person("Tom");
if(person != null){
String name = person.getLastName();
if(name != null){
return name.toLowerCase();
} else {
return null;
}
} else {
return null;
}

优化后:

Optional<Person> optional = Optional.ofNullable(new Person("Tom"));
return optional.map(p -> p.getLastName()).map(name -> name.toUpperCase()).orElse(null);

JDK8的Optional用法的更多相关文章

  1. JDK8,Optional

     作为程序员,你肯定遇到过NullPointerException, 这个异常对于初出茅庐的新人, 还是久经江湖的老手都是不可避免的痛, 可又是那么的无能为力,为了解决它,你只能在使用某个值之前,对其 ...

  2. Optional用法与争议点

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介 要说Java中什么异常最容易出现,我想NullPointerException一定当仁不让,为了解决这种null值 ...

  3. JDK8中`Optional.orElse()` 和`Optional.orElseGet()`之间的区别

    看例子就明白了 ``` static String B() { System.out.println("B()..."); return "B"; } publ ...

  4. JDK8的LocalDateTime用法

    参考资料:好好学Java  https://mp.weixin.qq.com/s/Dd_7yUh3lq3TqE2cjsYXvw JDK8新特性里提供了3个时间类:LocalDate.LocalTime ...

  5. java8 :: 用法 (JDK8 双冒号用法)

    https://www.cnblogs.com/tietazhan/p/7486937.html

  6. JDK8新特性之Optional

    Optional是什么 java.util.Optional Jdk8提供Optional,一个可以包含null值的容器对象,可以用来代替xx != null的判断. Optional常用方法 of ...

  7. 给女朋友讲解什么是Optional【JDK 8特性】

    前言 只有光头才能变强 前两天带女朋友去图书馆了,随手就给她来了一本<与孩子一起学编程>的书,于是今天就给女朋友讲解一下什么是Optional类. 至于她能不能看懂,那肯定是看不懂的.(学 ...

  8. jdk8新特性-stream

    一.什么是流stream 1.可理解为高级版本的 Iterator 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的. 2.单向,不可往复 数据只能遍历一次,遍历过一次后即用尽了,就好比 ...

  9. java代码之美(16) ---Java8 Optional

    Java8 Optional 一句话介绍Optional类:使用JDK8的Optional类来防止NullPointerException(空指针异常)问题. 一.前言 在我们开放过程中,碰到的异常中 ...

随机推荐

  1. js返回上一页并刷新思路

    在网上找了很多办法,比如window.history.go(-1):window.history.go(0): 试了下根本没用(不知道是不是我哪里写错了),想着在上一个页面写一个关闭页面并刷新的方法, ...

  2. day18 装饰器(下)+迭代器+生成器

    目录 一.有参装饰器 1 前提 2 如何使用有参装饰器 3 有参装饰器模板 4 修正装饰器 二.迭代器 1 什么是迭代器 2 为什么要有迭代器 3 如何用迭代器 3.1 可迭代对象 3.2 可迭代对象 ...

  3. python基础之打/解包及运算符与控制流程

    python基础之打/解包及运算符与控制流程 python中的解压缩(即序列类型的打包和解包) python提供了两个设计元祖和其他序列类型的处理的便利,也就是自动打包与自动解包功能,比如: data ...

  4. mongodb(一):数据库安装,部署(windows)

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10885038.html,多谢~=.= 安装MongoDB 双击运行msi文件,一直“Next”. ...

  5. 数据可视化之PowerQuery篇(四)二维表转一维表,看这篇文章就够了

    https://zhuanlan.zhihu.com/p/69187094 数据分析的源数据应该是规范的,而规范的其中一个标准就是数据源应该是一维表,它会让之后的数据分析工作变得简单高效. 在之前的文 ...

  6. Python之进程、线程、协程篇

    本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者 ...

  7. python 并发专题(十四):asyncio (三)实战

    https://www.cnblogs.com/wongbingming/p/9124142.html 在实战中,将会用到以下知识点: 多线程的基本使用 Queue消息队列的使用 Redis的基本使用 ...

  8. C#-CLR note - 26线程

    开篇 async/wait的使用 static async Task Main(string[] args) { Console.WriteLine("start-- "); va ...

  9. 02-URLConf调度器

    1.工作原理 django通过urlconf来映射视图函数,只区分路径,不区分http方法 Django确定要使用的根URLconf模块,一般是在settings中的ROOT_URLCONF设置的值. ...

  10. 盘点JMeter不为人知那一些细节

    Jmeter工作原理 向服务器提交请求,并从服务器取回请求返回的结果.即建立一个线程池,多线程运行取样器产生大量负载,在运行过程中通过断言来验证结果的正确性,通过监听器来记录测试结果. 文章内容以Jm ...