JDK8新特性-Optional类
个人简介
作者是一个来自河源的大三在校生,以下笔记都是作者自学之路的一些浅薄经验,如有错误请指正,将来会不断的完善笔记,帮助更多的Java爱好者入门。
文章目录
- 个人简介
- JDK8新特性-Optional类
- 教程概述
- Optional的简单介绍
- 简单对比两种防止空指针方式
- 准备环境
- JDK1.8之前的普通方式
- JDK1.8之后使用Optional方式
- 创建Optional实例的三种方式
- of方法
- of方法创建Optional实例
- 为什么of方法的值不能为null,否则就会报错?源码分析
- ofNullable方法
- ofNullable方法创建Optional实例
- 为什么ofNullable方法的值可以为null?源码分析
- empty方法
- empty方法源码分析
- isPresent方法
- isPresent方法的使用
- isPresent源码分析
- ifPresent方法
- ifPresent方法使用
- ifPresent源码分析与isPresent区别
- orElse方法
- orElse方法源码解析
- orElseGet方法
- orElseGet方法使用
- orElseGet源码解析
- orElse和orElseGet区别
- orElseThrow方法
- filter方法
- map方法
- 案例:传入User对象,返回UserDetail对象
JDK8新特性-Optional类
教程概述
- 本教程附有非常多的例子,看完肯定能懂Optional类!
- 看完本教程,对于Optional类的api基本的使用完全没有问题!
- 本教程借鉴过很多其他大佬的教程,并进行总结创新,难免会有相同之处。
- 本教程会涉及一些源码。
Optional的简单介绍
- 每个程序员都会遇到的Exception其中最常见的莫过于NullPointerException异常,为了避免这个异常的发生我们常用if去判断对象是否为null再进行使用,这样就显得很乏味,于是Optional出现了。
- Optional的好处是:使用链式编程的方式更优雅的解决NullPointerException问题
简单对比两种防止空指针方式
准备环境
//准备环境User user = new User();user.setUsername("aaa");UserDetail userDetail = new UserDetail();userDetail.setIcon("icon");userDetail.setSignature("ccccd");user.setUserdetail(userDetail);UserAuthority userAuthority = new UserAuthority();userAuthority.setAuthority(2);userDetail.setUserAuthority(userAuthority);
class User{private String username; //用户名private UserDetail userdetail; //用户细节//省略getter/setter/tostring
}
class UserDetail{private String icon;//头像private String signature;//个性前面private UserAuthority userAuthority; //用户权限//省略getter/setter/tostring
}
class UserAuthority{private int authority; //权限//省略getter/setter/tostring
}
JDK1.8之前的普通方式
//JDK1.8之前,如果我们要查询用户权限。要这样子if(user!=null){if(user.getUserdetail()!=null){if(user.getUserdetail().getUserAuthority()!=null){System.out.println("JDK1.8之前查权限:"+user.getUserdetail().getUserAuthority().getAuthority());}else {System.out.println(333);}}}
JDK1.8之后使用Optional方式
//JDK1.8之后,如果我们要查询用户权限。可以使用Optional类Integer integer = Optional.ofNullable(user)//还没有经过map,当前stream是:user对象//经过了第一次map变成userdetail对象.map(u -> u.getUserdetail())//经过了第二次userauthority.map(ud -> ud.getUserAuthority())//authority.map(a -> a.getAuthority())//如果哪一层map出现null了,则会直接跳到下面这个orElse去执行。.orElse(333);System.out.println(integer);
创建Optional实例的三种方式
- 由于Optional类的构造方法全部都被private修饰,所以不能通过new关键字去创建,必须要通过以下三种方法进行创建。
private Optional() {this.value = null;}private Optional(T value) {this.value = Objects.requireNonNull(value);}
- Optional类被final进行修饰,故无法对它进行继承。
public final class Optional<T> {Optional类核心代码
}
of方法
of方法的特点:
- 不允许Optional的value为null,否则会立刻报错NullPointerException异常
of方法创建Optional实例
Optional<String> stringOptional = Optional.of("hello");
为什么of方法的值不能为null,否则就会报错?源码分析
public static <T> Optional<T> of(T value) {return new Optional(value);}private Optional(T value) {this.value = Objects.requireNonNull(value);}
Objects.requireNonNull源码
public static <T> T requireNonNull(T obj) {if (obj == null) {throw new NullPointerException();} else {return obj;}}
ofNullable方法
- ofNullable的value可以为null,并且不会报错
ofNullable方法创建Optional实例
Optional<Object> optional = Optional.ofNullable("hello");
为什么ofNullable方法的值可以为null?源码分析
public static <T> Optional<T> ofNullable(T value) {return value == null ? empty() : of(value);}
- 可以看出当value==null时,此时Optional的对象由empty方法创建,而empty方法的返回的Optional对象是由Optional类内部实例化的一个Optional实例,名字为EMPTY,并且是被private static final修饰。
private static final Optional<?> EMPTY = new Optional(); public static <T> Optional<T> empty() {Optional<T> t = EMPTY;return t;}
- 当value!=null时,则调用of方法进行创建,虽然of方法不能为null否则会报错,但是此时的value一定不为空,所以of方法一定不会报错。故这个ofNullable方法一定不会报错。
empty方法
- empty方法的返回的Optional对象是由Optional类内部实例化的一个Optional实例,名字为EMPTY,并且是被private static final修饰
empty方法源码分析
private static final Optional<?> EMPTY = new Optional(); public static <T> Optional<T> empty() {Optional<T> t = EMPTY;return t;}
isPresent方法
- 判断Optional的value是否存在,也就是是否不为null
isPresent方法的使用
//准备环境User user = new User();user.setUsername("aaa");UserDetail userDetail = new UserDetail();userDetail.setIcon("icon");userDetail.setSignature("ccccd");user.setUserdetail(userDetail);UserAuthority userAuthority = new UserAuthority();userAuthority.setAuthority(2);userDetail.setUserAuthority(userAuthority);Optional<User> optionalUser = Optional.ofNullable(user);boolean present = optionalUser.isPresent();System.out.println("Optional的value是否存在?"+present);if(present){System.out.println(optionalUser.get()); //此时一定不为null,present为true代表存在}
isPresent源码分析
private final T value; public boolean isPresent() {return this.value != null;}
Optional一旦创建,就会往value放值,isPresent方法的作用就是判断value是否不为空,也就是是否存在
还有就是String s="",也代表存在,而String s=null,则是不存在。
ifPresent方法
- 一定要区别于isPresent和ifPresent方法。
ifPresent方法使用
Optional<String> optionalS = Optional.ofNullable(null);//如果Optional的value存在则会执行System.out.println("ifpresent="+s)这段代码,反之则不会执行。optionalS.ifPresent(s->System.out.println("ifpresent="+s));
ifPresent源码分析与isPresent区别
public void ifPresent(Consumer<? super T> action) {if (this.value != null) {action.accept(this.value);}}
- ifPresent没有返回值,接收参数是lambda表达式,如果this.value不会空才会执行这个lambda表达式。
public boolean isPresent() {return this.value != null;}
- 而isPresent方法是不用参数的,并且返回boolean值,也是判断this.value是否存在。本质上都差不多
orElse方法
- 当optional的value为null,或者经过map映射的optional的value为null,则会执行orElse方法
- 本质上orElse方法就是当optional的value为null时的兜底方法。
Optional<String> optional1 = Optional.ofNullable("hello");String s1 = optional1.orElse("orElse111---");System.out.println(s1); //helloOptional<String> optional2 = Optional.ofNullable(null);String s2 = optional2.orElse("orElse222---");System.out.println(s2); // orElse222---
orElse方法源码解析
public T orElse(T other) {return this.value != null ? this.value : other;}
意思是如果this.value如果存在,返回结果就是这个value,如果value不存在,则会返回other,other就是我们的兜底方案。
orElseGet方法
- orElse和orElseGet差不多,只是形参不同,orElseGet需要传入lambda的Supplier 表达式,格式为:()->xxx
orElseGet方法使用
Object o = Optional.ofNullable(null).orElseGet(() -> "orElseGet");System.out.println(o);
orElseGet源码解析
public T orElseGet(Supplier<? extends T> supplier) {return this.value != null ? this.value : supplier.get();}
如果this.value存在,则返回this.value,反之则使用传过来的supplier的值
orElse和orElseGet区别
- 如果optional的value!=null,orElse方法也要执行。即使value不为null,也要执行。
- 而orElseGet方法只有value==null才会执行
- 对于orElse方法这种特性是极其浪费性能的。
private static String getName() {System.out.println("getname");return "张三";} String s1 = Optional.ofNullable("666").orElse(getName());System.out.println(s1);
输出
getname
666
private static String getName() {System.out.println("getname");return "张三";} String s2 = Optional.ofNullable("777").orElseGet(() -> getName());System.out.println(s2);
输出
777
orElseThrow方法
- 其实就是当value为null时,兜底方法就是抛自定义异常。
String n=null;String s = Optional.ofNullable(n).orElseThrow(() -> new RuntimeException("excp"));System.out.println(s);
输出
Exception in thread "main" java.lang.RuntimeException: excpat com.jdk8.optional.Optional06.lambda$main$0(Optional06.java:11)at java.base/java.util.Optional.orElseThrow(Optional.java:408)at com.jdk8.optional.Optional06.main(Optional06.java:11)
filter方法
filter方法的使用请参照我的一篇Stream流的教程。。。
- 其实filter过滤就像是if语句,只把符合条件的筛选出来。
使用
//准备环境User user1 = new User();user1.setUsername("aaa");User user2 = new User();user2.setUsername("bbb");User user3 = new User();user3.setUsername("ccc");Optional<User> optionalUser1 = Optional.ofNullable(user1).filter(x -> x.getUsername().equals("bbb"));System.out.println(optionalUser1);//Optional.emptyOptional<User> optionalUser2 = Optional.ofNullable(user2).filter(x -> x.getUsername().equals("bbb"));//Optional[User{username='bbb', userdetail=null}]System.out.println(optionalUser2);
输出
Optional.empty
Optional[User{username='bbb', userdetail=null}]
map方法
map方法的使用请参照我的一篇Stream流的教程。。。
- map的作用就是把一个对象进行转换,比如下面的,map的作用就是把User对象转换成UserDetail对象。
案例:传入User对象,返回UserDetail对象
//准备环境User user = new User();user.setUsername("aaa");UserDetail userDetail = new UserDetail();userDetail.setIcon("icon");userDetail.setSignature("ccccd");user.setUserdetail(userDetail);UserAuthority userAuthority = new UserAuthority();userAuthority.setAuthority(2);userDetail.setUserAuthority(userAuthority);//传入User对象,返回UserDetail对象Optional<UserDetail> optionalUserDetail =Optional.of(user).map(User::getUserdetail);System.out.println(optionalUserDetail.get());
输出
UserDetail{icon='icon', signature='ccccd', userAuthority=UserAuthority{authority=2}}
JDK8新特性-Optional类相关推荐
- JDK8新特性 - Optional类
引言 Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException).本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空 ...
- Java JDK8新特性Optional类
Optional类 1.该类java.util包下,是不能被继承的泛型类即:public final class Optional<T>. 2.该类有两个私有属性: T value和 静态 ...
- Java8新特性——Optional 类
文章目录 前言 Optional 类 1.概述 2.API介绍 of ofNullable empty isPresent get ifPresent orElse orElseGet orElseT ...
- Java8新特性 Optional类
作为开发人员每天与NullPointerException斗智斗勇.每接收到参数或调用方法获得值得判断一下是否为null.稍不留意,空指针异常就像幽灵一样出现了.这篇文章我们来学习Java8是如何通过 ...
- Java8新特性Optional类
这里写自定义目录标题 Java8 Optional 类 前言 创建 Optional 实例 Optional API常用接口的用法 get()方法 isPresent()方法 isPresent()方 ...
- java 8 optional 类,Java8新特性-Optional类
Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念.并且可以避免空指 ...
- Java8新特性-Optional类
概念:Optional<T> 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这 ...
- Java 8 新特性 Optional 类学习,理解并应用。NullPointerException空值检测
- JDK8 新特性流式数据处理
在学习JDK8新特性Optional类的时候,提到对于Optional的两个操作映射和过滤设计到JDK提供的流式出来.这篇文章便详细的介绍流式处理: 一. 流式处理简介 流式处理给开发者的第一感觉就是 ...
最新文章
- mooc python_MOOC python笔记(一):python语言概述
- 图解在emu8086中学习汇编语言数字比较程序
- SpringBoot 上传文件(单个、多个文件)
- Jenkins+GitLab+Docker+SpringCloud+Kubernetes实现可持续自动化微服务
- 物联网技术周报第 109 期: 从设计理念解读实时操作系统 RT-Thread
- Nginx从入门到掌握【(第3节(共3节)】
- LeetCode 513. 找树左下角的值(递归)
- Oracle安装基本步骤
- 楼房噪音模拟测试软件,房子不隔音?4种方法让你进入“静音”模式!
- CC2530单片机P1寄存器说明
- js笔记,自封装篇(二)之对象克隆
- python打印日历_用Python打印某年日历
- echarts图表和map地图
- 洛谷 P4238 【模板】多项式求逆 ntt
- Graphpad,经典绘图工具初学初探
- 如何快速生成gif动图表情包?教你制作gif表情包图片
- American Crew(R) ACUMEN™闪亮登场
- 不知道如何提高视觉语言大模型?浙大与联汇研究院提出新型多维度评测框架...
- Linq之GroupBy用法
- FDC2214-纸张计数显示装置