Optional

一、Optional类是什么?

Optional 类(java.util.Optional)是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在用Optional可以更好的表达这个概念。并且可以避免空指针。

二、Optional类常用的方法

1. 创建Optional实例

这个类型的对象可能包含值,也可能为空。

1.1 Optional.of(T)

创建一个Optional实例

    @Test
public void test01(){
////创建一个带泛型的Optional容器类
Optional<Employee> employee = Optional.of(new Employee());
System.out.println(employee.get()); //会报空指针异常
Optional<Employee> employee1 = Optional.of(null);
System.out.println(employee1.get()); }
}

这里我们需要注意,Optional.of(null),of方法传null时,会报NullPointException.

1.2 Optional.empty()

创建一个空的Optional实例

    @Test
public void test02(){
//构建了一个空的Optional实例,里面没有任何东西
Optional<Employee> employee = Optional.empty();
System.out.println(employee.get());//输出 java.util.NoSuchElementException: No value present
}

1.3. Optional.ofNullable(T t)

Optional类中的of()方法不允许包装null,但是ofNullable()方法可以,传递到该方法中的若为null,则构建一个空的Optional实例

    @Test
public void test03(){
//不会报空指针异常
//Optional类中的of()方法不允许包装null,但是ofNullable()方法可以,传递到该方法中的若为null,则构建一个空的Optional实例
Optional<Employee> employee2 = Optional.ofNullable(null);
if(employee2.isPresent()){
System.out.println(employee2.get());
}else{
System.out.println("------------");
}
}

我们来看一下ofNullable源码

    public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}

即如果传进来的是null则直接调用了empty(),不为null时才调用of(value)。

1.4. 小结

这个类型的对象可能包含值,也可能为空。我们可以使用Optional.empty()方法创建一个空的Optional,也可以使用of() 和 ofNullable() 方法创建包含值的 Optional。这俩方法的不同之处在于如果把null值作为参数传递进去,of()方法会抛出NullPointerException。所以,我们应该在对象不为 null的时候使用 of(),对象即可能是 null 也可能是非null,使用 ofNullable() 方法。

2.访问Optional对象的值

2.1 get()获取值

    @Test
public void test01(){
////创建一个带泛型的Optional容器类
Optional<Employee> employee = Optional.of(new Employee());
//获取值
System.out.println(employee.get());
}

从 Optional 实例中取回实际值对象的方法之一是使用 get() 方法。不过,这个方法会在值为null的时候抛出异常,为了避免我们要先验证是否有值。

2.2 isPresent()验证是否有值

    @Test
public void test03(){
//不会报空指针异常
//Optional类中的of()方法不允许包装null,但是ofNullable()方法可以,传递到该方法中的若为null,则构建一个空的Optional实例
Optional<Employee> employee2 = Optional.ofNullable(null);
//判断是否存在
if(employee2.isPresent()){//存在
System.out.println(employee2.get());
}else{//不存在
System.out.println("------------");
}
}

2.3 ifPresent()

检查是否有值的时候还可以用ifPresent(),该方法除了执行检查,还可以接受一个Consumer(消费者)参数,如果对象不是空的,就执行传入的Lambda表达式。

    @Test
public void test04(){
Optional<Employee> employee2 = Optional.ofNullable(new Employee());
//如果对象不是空的,就执行传入的Lambda表达式。
employee2.ifPresent(e -> System.out.println(e.getAge()));
}

3. 返回默认值

Optional类提供API用以返回对象值,或者在对象为空的时候返回默认值。

3.1 orElse(T t)

如果调用对象包含有值,那么返回该值,否则返回orElse()方法中的对象。

    @Test
public void test05(){
Optional<Employee> op = Optional.ofNullable(new Employee());
Employee em = op.orElse(new Employee("默认姓名", 20, 1000));
System.out.println(em);//打印Employee{name='null', age=0, salary=0.0} Optional<Employee> op1 = Optional.ofNullable(null);
Employee em1 = op1.orElse(new Employee("默认姓名", 20, 1000));
System.out.println(em1);//打印Employee{name='默认姓名', age=20, salary=1000.0}
}

3.2 orElseGet(Supplier s)

    @Test
public void test06(){
Optional<Employee> op = Optional.ofNullable(new Employee());
Employee em = op.orElseGet(() -> new Employee("默认姓名", 20, 1000));
System.out.println(em);//打印Employee{name='null', age=0, salary=0.0} Optional<Employee> op1 = Optional.ofNullable(null);
Employee em1 = op1.orElseGet(() -> new Employee("默认姓名", 20, 1000));
System.out.println(em1);//打印Employee{name='默认姓名', age=20, salary=1000.0}
}

3.3 orElse(T t)和orElseGet(Supplier s)的不同

先来看看传入对象都为null时


public Employee createNewEmployee(){
System.out.println("==========创建一个新对象====");
return new Employee("默认姓名1", 20, 1000);
} @Test
public void test07(){ //传入对象都为null时
Employee e = null;
Optional<Employee> op = Optional.ofNullable(e);
System.out.println("-----orElse----");
Employee em = op.orElse(createNewEmployee());
System.out.println("-----orElseGet----");
Employee em1 = op.orElseGet(() -> createNewEmployee());
}

运行结果:两种方法都调用了 createNewEmployee() 方法


-----orElse----
==========创建一个新对象====
-----orElseGet----
==========创建一个新对象====
    //不同之处
@Test
public void test08(){
//传入对象都不为null时
Employee e = new Employee("默认姓名", 20, 1000);
Optional<Employee> op = Optional.ofNullable(e);
System.out.println("-----orElse----");
Employee em = op.orElse(createNewEmployee());
System.out.println("-----orElseGet----");
Employee em1 = op.orElseGet(() -> createNewEmployee());
}

运行结果,只有一个方法调用了createNewEmployee()

-----orElse----
==========创建一个新对象====
-----orElseGet----

这个例子说明,两个 Optional 对象都包含非空值,两个方法都会返回对应的非空值。不过,orElse() 方法仍然创建了 User 对象。与之相反,orElseGet() 方法不创建 User 对象。

在执行较密集的调用时,比如调用 Web 服务或数据查询,这个差异会对性能产生重大影响。

4. 转换值

4.1 map(Function f)

若有值则对其处理,并返回处理后的Optional,否则返回Optional.empty()。

    @Test
public void test09(){ String str = Optional.ofNullable(new Employee())
.map(Employee::getName).orElse("张三");
System.out.println(str);//打印输出张三
Employee e = new Employee("默认姓名", 20, 1000);
String str2 = Optional.ofNullable(e)
.map(Employee::getName).orElse("张三");
System.out.println(str2);//打印输出默认姓名 }

4.2 flatMap(Function mapper)

与map类似,但要求返回值必须是Optional。

    @Test
public void test10(){
Employee em = new Employee("默认姓名", 20, 1000); //map
Optional<String> s1 = Optional.ofNullable(em)
.map(Employee::getName);
System.out.println(s1);
//flatMap 要求返回的是Optional 避免空指针
Optional<String> s2 = Optional.ofNullable(em)
.flatMap(e -> Optional.of(e.getName()));
System.out.println(s2); }

5. 过滤值

除了转换值之外,Optional 类也提供了按条件“过滤”值的方法。

5.1 filter()

filter() 接收一个Predicate参数,返回测试结果为true的值,如果测试结果为false,会返回一个空的Optional。

    @Test
public void test11(){ //map
Optional<Employee> employee = Optional.ofNullable(new Employee())
.filter(e -> e.getName() != null);
System.out.println(employee);//返回一个空的Optional Optional.empty
Employee em = new Employee("默认姓名", 20, 1000); Optional<Employee> employee1 = Optional.ofNullable(em)
.filter(e -> e.getName() != null);
System.out.println(employee1);//Optional[Employee{name='默认姓名', age=20, salary=1000.0}] }

如果通过过滤器测试,result 对象会包含非空值。

三、总结

Optional类其实就是一个封装了一个元素的容器,而这个元素可以是null也可以是其它任意类型的。Optional是Java语言的有益补充,它旨在减少代码中的NullPointerExceptions,虽然不能完全消除这些异常,他也是精心设计,自然融入了Java8函数式支持的功能

Java8的新特性--Optional的更多相关文章

  1. JAVA8新特性Optional,非空判断

    Optional java 的 NPE(Null Pointer Exception)所谓的空指针异常搞的头昏脑涨, 有大佬说过 "防止 NPE,是程序员的基本修养." 但是修养归 ...

  2. 简单了解JAVA8的新特性

    JAVA8新特性会颠覆整个JAVA程序员的编程习惯 甚至如果您坚守JAVA7之前的编程习惯,今后你看比较年轻的程序员写的JAVA代码都会无法理解 所以为了保证不脱钩,我觉得有必要学习JAVA8的新特性 ...

  3. java8的新特性以及用法简介

    1. 介绍 2 接口的默认方法 2 lambda表达式 2.1 函数式接口 2.2 方法与构造函数引用 2.3 访问局部变量 2.4 访问对象字段与静态变量 3. 内建函数式接口 3.1 Predic ...

  4. Java8 Stream新特性详解及实战

    Java8 Stream新特性详解及实战 背景介绍 在阅读Spring Boot源代码时,发现Java 8的新特性已经被广泛使用,如果再不学习Java8的新特性并灵活应用,你可能真的要out了.为此, ...

  5. Java8常用新特性实践

    前言: 时下Oracle开速迭代的Java社区以即将推出Java10,但尴尬的是不少小中企业仍使用JDK7甚至JDK6开发. 从上面列出的JDK8特性中我们可以发现Java8的部分特性很明显的是从Sc ...

  6. JDK1.8新特性——Optional类

    JDK1.8新特性——Optional类 摘要:本文主要学习了JDK1.8新增加的Optional类. 部分内容来自以下博客: https://www.cnblogs.com/1ning/p/9140 ...

  7. Java8 新特性 Optional 类

    Optional 类的简介   Optional类的是来自谷歌Guava的启发,然后就加入到Java8新特性中去了.Optional类主要就是为子决解价值亿万的错误,空指针异常.   Optional ...

  8. Java8新特性——Optional

    前言 在开发中,我们常常需要对一个引用进行判空以防止空指针异常的出现.Java8引入了Optional类,为的就是优雅地处理判空等问题.现在也有很多类库在使用Optional封装返回值,比如Sprin ...

  9. Java8新特性--Optional

    Java 8引入了一个新的Optional类.Optional类的Javadoc描述如下: 这是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会 ...

随机推荐

  1. 二分类问题中混淆矩阵、PR以及AP评估指标

    仿照上篇博文对于混淆矩阵.ROC和AUC指标的探讨,本文简要讨论机器学习二分类问题中的混淆矩阵.PR以及AP评估指标:实际上,(ROC,AUC)与(PR,AP)指标对具有某种相似性. 按照循序渐进的原 ...

  2. 让你像黑客一样写代码(not really)

    让你像黑客一样写代码(not really) http://poznan.tvp.pl 这是一个波兰的视频网站. poznan 波兹南(波兰城市 视屏链接 http://video.sina.com. ...

  3. <U+200B> for, Zero Width Space ❌

    <U+200B> for, Zero Width Space zsh, bash https://www.cnblogs.com/xgqfrms/p/14233264.html#47944 ...

  4. vue & async mounted

    vue & async mounted refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  5. why 2020 you should create a new modern website with web fullstack

    why 2020 you should create a new modern website with web fullstack Full-Stack Web Development Front- ...

  6. Azure 计费 & 成本管理 & 取消 Azure 订阅

    Azure 计费 & 成本管理 & 取消 Azure 订阅 https://docs.microsoft.com/zh-cn/azure/cost-management-billing ...

  7. 2021 NGK生态所体验好、交易快 引人注目!

    据悉,NGK计划于2021年2月15日正式上线自己的生态所(时间待定),目的在于满足NGK生态建设者对于NGK几大币种的交易等需求,如NGK.BGV.SPC.USDN.VAST等.只要上NGK生态所, ...

  8. Renice INC:不同颜色的酒帽所代表的意义

    酒帽就是酒瓶上方的热缩胶帽/锡帽/蜡封,也就是开瓶前要割掉的那一层保护物,所有的法国酒在酒帽上,都会有一个圆形贴纸,除了有不同颜色外,上面还有一串号码,有可能很多人在喝酒时都不会对这个酒帽有更多的在意 ...

  9. 在vscode中用Git管理项目

    1.新建仓库-->填写仓库名称-->一定要将对钩去掉-->公开-->创建 Git全局设置: git config --global --add user.name " ...

  10. Vue使用&nbsp空白占位符

    当有时候需要在页面显示时显示空格时,可以使用 ,但是使用这个占位符时,无论写多少个,就只能显示一个空格.要想显示多个空格进行占位,这种方式显然是可行的,解决方法是使用转义字符. 先看代码: <t ...