jdk1.8 -- optional 的使用
一.optional的介绍
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。

本文将从三方面来讲解optional:
1.Optional的构建
2.Optional的获取
3.Optional的复合操作
下面先讲解在没有Optional之前我们是如何对null值进行判断的
class Persion{
private Car car;
public Car getCar() {
return this.car;
}
}
class Car{
private Brand insurance;
public Brand getInsurance() {
return this.insurance;
}
}
class Brand {
private String name;
public String getName() {
return this.name;
}
}
public class BeforeOptional {
public static void main(String[] args) {
getBrandName(new Persion());
getBrandNameDefault(new Persion());
}
private static String getBrandName(Persion persion) {
if(null !=persion.getCar()) {
Car car = persion.getCar();
if(null !=car.getInsurance()) {
Brand insurance = car.getInsurance();
if(null !=insurance.getName()) {
return insurance.getName();
}
}
}
return "";
}
private static String getBrandNameDefault(Persion persion) {
String defaultValue = "UNKNOW";
if(null ==persion)
return defaultValue;
Car car = persion.getCar();
if(null == car)
return defaultValue;
Brand insurance = car.getInsurance();
if(null == insurance)
return defaultValue;
return insurance.getName();
}
}
显然,我们需要通过代码来硬编码实现对象引用变量的判断
二.Optional API的操作
//********************** 1. Optional 的构建**********************
//1.1创建一个空的optional(内部new了一个空的optional),不支持get方法,会报异常NoSuchElementException
Optional<Brand> empty = Optional.<Brand>empty();
empty.get();
//1.2创建一个optional,传入的值不能为null,返回Optional<Object>,为null时会报NullPointerException
Optional<Brand> of = Optional.of(new Brand());
System.out.println(of.get());
//1.3创建一个可空可有的optional,对前2种的总结(如果传null,走empty方法,非null,走of方法)
Optional<Brand> brand = Optional.ofNullable(new Brand());
Optional<Object> ofNullable2 = Optional.ofNullable(null);
//********************** 2. Optional 的获取操作**********************
//2.1 如果当前有值,返回这个值,否则报NoSuchElementException("No value present");
brand.get();
//2.2 如果有值,会传出insurance实例,如果没值,会给出传入的参数;(参数是supplier)
brand.orElseGet(Brand::new);
//2.3 如果有值,会传出insurance实例,如果没值,会给出传入的参数;(参数是Insurance 实例)
brand.orElse(new Brand());
//2.4 如果有值,会传出insurance实例,如果没值,可以抛出异常
brand.orElseThrow(RuntimeException::new);
brand.orElseThrow(()->new RuntimeException("not have reference"));
//********************** 3. Optional 的复合操作**********************
//3.1 返回一个boolean值
brand.isPresent();
//3.2 如果有值,有值时可以进行操作(consumer操作)
brand.ifPresent(System.out::println);
//3.3 filter操作,它会通过predicate操作,对brand 以及表达式进行非空的验证,通过后,方能得到结果
brand.filter(b->b.getName() == null).get();
//3.4 map操作:同filter,不同之处在于map会改变get到的类型
brand.map(b->b.getName()).get();
//3.5 flatMap 得到复合操作后的Optional<flatMap参数得到的值的optional>
Optional<Per> per = Optional.ofNullable(new Per());
Optional<Optional<Car2>> map = per.map(Per::getCar); //这个是对Optional<optional<Car2>进行了再一次的封装
Optional<Car2> flatMap = per.flatMap(Per::getCar); //这个得到的还是原来的Optional<Object>
我们回过头来解决开篇中的方法
class Persion2{
private Optional<Car2> car; //注意这里要加上Optional的改写
public Optional<Car2> getCar() {
return car;
}
}
class Car2{
private Optional<Brand2> Brand2; //注意这里要加上Optional的改写
public Optional<Brand2> getBrand2() {
return Brand2;
}
}
class Brand2{
private String name;
public String getName() {
return this.name;
}
}
public static String getInsuranceName(Persion2 per) {
return Optional.ofNullable(per).flatMap(Persion2::getCar).flatMap(Car2::getBrand2).map(b->b.getName()).orElse("Unknown"); //是不是一行代码就搞定了
}
jdk1.8 -- optional 的使用的更多相关文章
- JDK1.8新特性——Optional类
JDK1.8新特性——Optional类 摘要:本文主要学习了JDK1.8新增加的Optional类. 部分内容来自以下博客: https://www.cnblogs.com/1ning/p/9140 ...
- JDK1.8新特性之Optional
概念 Optional 是JDK1.8中出现的一个容器类,代表一个值存在或者不存在.原来使用null表示一个值不存在,现在Optional可以更好的表达这个概念.并且可以避免空指针异常. 场景分析 需 ...
- Linux配置JDK1.7和Resin4.0
1.安装JDK1.7 (1)下载 官网下载路径:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-18802 ...
- JDK各个版本的新特性jdk1.5-jdk8
JDK各个版本的新特性 对于很多刚接触java语言的初学者来说,要了解一门语言,最好的方式就是要能从基础的版本进行了解,升级的过程,以及升级的新特性,这样才能循序渐进的学好一门语言.今天先为大家介绍一 ...
- JAVA 8 Optional类介绍及其源码
什么是Optional对象 Java 8中所谓的Optional对象,即一个容器对象,该对象可以包含一个null或非null值.如果该值不为null,则调用isPresent()方法将返回true,且 ...
- JAVA JDK1.5-1.9新特性
1.51.自动装箱与拆箱:2.枚举(常用来设计单例模式)3.静态导入4.可变参数5.内省 1.61.Web服务元数据2.脚本语言支持3.JTable的排序和过滤4.更简单,更强大的JAX-WS5.轻量 ...
- jdk各个版本的新特性(jdk1.7,1.8,1.9)
用了这么久的jdk,应该会有很多人和我一样,不知道各个版本的jdk的一些新特性,这里简单总结一下.. jdk1.7新特性: 1.在Switch中可以用String字符串 2.对Java集合(Colle ...
- 【新特性】JDK1.8
一.简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性.在本文中我们将学习这些新特性,并用实际的 ...
- 学习笔记 Optional
今天学习到的一种新的防止空指针的方法下面是我自己写的一个例子:节省空间,bean的get set 省略... /** * 类目 * @author 唐 * @date 2018/5/6 17:45 * ...
随机推荐
- Activiti服务类- TaskService服务类
一共72个接口 1.创建任务(2个方法)//创建与任何流程实例无关的新任务.Task newTask();//使用用户定义的任务id创建一个新任务.Task newTask(String taskId ...
- [Luogu] 染色
https://www.luogu.org/problemnew/show/P2486 qizha 为什么会wa #include <cstdio> #include <cmath& ...
- Win内核原理与实现学习笔记1-windows内核版本列表
- 内存管理4-Autoreleasepool
自动释放池是OC里面的一种内存回收机制,一般可以将一些临时变量添加到自动释放池中,统一回收释放,当自动释放池销毁时,池里面的所有对象都会调用一次release,也就是计数器会减1,但是自动释放池被销毁 ...
- Spring事务管理的一些注意点
在<Spring Boot事务管理(下)>中,已经介绍了如果在 protected.private 或者默认可见性的方法上使用@Transactional,事务将是摆设,也不会抛出任何异常 ...
- centos7 设置 防火墙 开机自启
CentOS 7.0默认使用的是firewall作为防火墙,之前版本是使用iptables. 1.设置firewall开机启动 systemctl enable firewalld 2.禁止firew ...
- JAVA的main方法
在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方 法有很大的不同,比如方法的名字必须是main,方法必须 ...
- 【I·M·U_Ops】------Ⅰ------ IMU自动化运维平台设想
说明本脚本仅作为学习使用,请勿用于任何商业用途.本文为原创,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. #A 搞这个平台的初心 由于之前呆的单位所有IT相关硬件资源都要我们 ...
- IO注意事项
read()方法返回值为什么是int? 因为字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到1111111 ...
- pip使用笔记
例子: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -U funcat -i: 指定库的安装源 -U:升级 原来已经安装的包,不带U ...