相关阅读

【小家java】java5新特性(简述十大新特性) 重要一跃
【小家java】java6新特性(简述十大新特性) 鸡肋升级
【小家java】java7新特性(简述八大新特性) 不温不火
【小家java】java8新特性(简述十大新特性) 饱受赞誉
【小家java】java9新特性(简述十大新特性) 褒贬不一
【小家java】java10新特性(简述十大新特性) 小步迭代
【小家java】java11新特性(简述八大新特性) 首个重磅LTS版本


【小家java】java8新特性之—Base64加密和解密原理
【小家java】java8新特性之—反射获取方法参数名
【小家java】java8新特性之—全新的日期、时间API(完全实现了JSR 310规范)
【小家java】java8新特性之—Optional的使用,避免空指针,代替三目运算符
【小家java】java8新特性之—lambda表达式的的原理
【小家java】java8新特性之—函数式接口(Supplier、Consumer、Predicate、Function、UnaryOperator,通往高阶设计的好工具)
【小家java】java8新特性之—方法引用
【小家java】java8新特性之—Stream API 详解 (Map-reduce、Collectors收集器、并行流)
【小家java】java8新特性之—外部迭代和内部迭代(对比性能差异)


每篇一句

涂磊:嘴不饶人心地善,心不饶人嘴上甜。心善之人能直言,嘴甜之人藏迷奸。宁交一个抬杠的鬼,也不交一个嘴甜的贼

空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到Google Guava的启发,Optional类已经成为Java 8类库的一部分。Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,使得我们就不用显式进行空值检测

创建一个Optional

Optional.of()或者Optional.ofNullable():创建Optional对象,差别在于of不允许参数是null,而ofNullable则无限制。

   // 参数不能是nullOptional<Integer> optional1 = Optional.of(10);// 参数可以是非nullOptional<Integer> optional2 = Optional.ofNullable(20);// 参数可以是nullOptional<Integer> optional3 = Optional.ofNullable(null);System.out.println(optional1); //Optional[10]System.out.println(optional2); //Optional[20]System.out.println(optional3); //Optional.empty

如上,我们直接输出了对象。但其实我们用容器装着,调用它的get方法来获取值。所以我们这么做:

System.out.println(optional1.get()); //10System.out.println(optional2.get()); //20System.out.println(optional3.get()); //java.util.NoSuchElementException: No value present

我们可以看到,第三句话抛出异常了。这是很多初学者非常容易犯的一个错误,如果里面装的是null值,是不能直接使用get方法的。正确的使用姿势:

if (optional3.isPresent()) {System.out.println(optional3.get());}

特殊对象:Optional.empty() 所有null包装成的Optional对象

public static void main(String[] args) {Optional<Integer> optional1 = Optional.ofNullable(null);Optional<Integer> optional2 = Optional.ofNullable(null);System.out.println(optional1 == optional2);// trueSystem.out.println(optional1 == Optional.<Integer>empty());// true//哪怕泛型类型都不一样  都是trueObject o1 = Optional.<Integer>empty();Object o2 = Optional.<String>empty();System.out.println(o1 == o2);// true }

从上面我们可以看出来,里面装null,不管泛型是啥,都是true。所以我们推测,它源码内部肯定维护着一个单例,源码:

 private static final Optional<?> EMPTY = new Optional<>();public static<T> Optional<T> empty() {Optional<T> t = (Optional<T>) EMPTY;return t;}

看源码里,证实了我们的猜测,没毛病。

isPresent():如果里面有值,返回true,否则返回false

需要注意,empty的就是false。所以一旦get就报错

    public static void main(String[] args) {System.out.println(Optional.ofNullable(null).isPresent()); //falseSystem.out.println(Optional.ofNullable(1).isPresent()); //trueSystem.out.println(Optional.empty().isPresent()); falseSystem.out.println(Optional.empty().get()); //java.util.NoSuchElementException: No value present}

ifPresent(Consumer consumer):如果option对象保存的值不是null,则调用consumer对象,否则不调用

Optional<Integer> optional1 = Optional.ofNullable(1);// 如果不是null,调用Consumer
optional1.ifPresent(new Consumer<Integer>() {@Overridepublic void accept(Integer t) {System.out.println("value is " + t);}

orElse(value):如果optional对象保存的值不是null,则返回原来的值,否则返回value。

orElseGet(Supplier supplier):功能与orElse一样,只不过orElseGet参数是一个生产者

本人特意把这两个拿出来放在一起,是因为其实很多人并不知道这两个到底有什么区别呢?下面我就具体来说说他们的区别(完全可以当作面试题,深度啊):

  public static void main(String[] args) {Optional.ofNullable(null).orElse(get("a"));Optional.ofNullable(null).orElseGet(() -> get("b"));}private static String get(String s) {System.out.println(s + ":~~我执行了~~");return s;}
输出:
a:~~我执行了~~
b:~~我执行了~~

再看下面这个例子:

 Optional.ofNullable("fill").orElse(get("a"));Optional.ofNullable("fill").orElseGet(() -> get("b"));
输出:
a:~~我执行了~~
(这里没有输出哦)

对比两者,我们终于发现区别了吧:如果Optional里面的值为null,那两者的效果一模一样。但是当里面的值为null时,我们发现orElse里面代码还是执行的,但是orElseGet里面就不会执行啦。所以使用起来是不是逼格高一点

orElseThrow(判空等场景特别有用)

如下代码,一句话搞定

Date startTime = new Date(Optional.of(req.getFromTime()).orElseThrow(() -> new MessagePopException("开始时间不能为空")));

如果不用这个我们得这么写

if(req.getFromTime() == null){throw new MessagePopException("开始时间不能为空");
}
Date startTime = req.getFromTime();

稍微麻烦点。使用orElseThrow显得更加的优雅

map(Function):对Optional中保存的值进行函数运算,并返回新的Optional(可以是任何类型)

flatMap():功能与map()相似 具体区别请参考streamAPI那一章


最后

Optional还有一个作用,三目运算符,可以代替三目运算符从而支持方法连缀。

        System.out.println(Optional.ofNullable("demo").orElse("a")); //demoSystem.out.println(Optional.ofNullable(null).orElse("a")); //a//或者 使用supplier生产System.out.println(Optional.ofNullable(null).orElseGet(() -> "abc")); //abc

下面使用的例子,还可以使用map映射:

    public static void main(String[] args) {//此处会直接抛出空指针异常//Optional<String> s = Optional.<String>of(null); //java.lang.NullPointerException//s可以直接使用,是empty,但是不能get,请配合isPresent()使用//Optional<String> s = Optional.<String>ofNullable(null);//System.out.println(s); //Optional.empty//System.out.println(s.get()); //java.util.NoSuchElementException: No value present//对它进行map操作,我们发现即使为null,我们map方法的x.toString()并没有报错  可谓非常友好//Optional<String> s = Optional.<String>ofNullable(null).map(x -> x.toString());//System.out.println(s); //Optional.empty//System.out.println(s.get()); //java.util.NoSuchElementException: No value present综上,我们可以经常这么来使用,可以很好的达到方法连缀的效果//1、非常简单的三目运算符  如果是null,就返回1  否则返回里面的值Integer v = Optional.<Integer>ofNullable(null).orElse(1);System.out.println(v); //1//2、三目运算符  结合map  可以实现类型的转换 非常安全且强大Integer vvv = Optional.<String>ofNullable(null).map(x -> Integer.valueOf(x)).orElse(100);System.out.println(vvv); //100}

关注A哥

Author A哥(YourBatman)
个人站点 www.yourbatman.cn
E-mail yourbatman@qq.com
微 信 fsx641385712
活跃平台
公众号 BAT的乌托邦(ID:BAT-utopia)
知识星球 BAT的乌托邦
每日文章推荐 每日文章推荐

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

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

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

  2. Java 8新特性:Optional类

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

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

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

  4. fundamentals\java\java8新特性-Lambda(译自oracle官网)

    Java8 Lambda Expressions 目录 Java8 Lambda Expression 典型使用场景:Ideal Use Case for Lambda Expressions 问题提 ...

  5. Java8新特性之Optional类(附代码案例)

    1. 概述 Optional< T >类是要给容器类,它可以保存类型T的值,代表这个值存在.或者仅仅保存null, 表示这个值不存在.原来用null表示一个值不存在,现在Optional可 ...

  6. 【小家java】java8新特性之---全新的日期、时间API(JSR 310规范),附SpringMVC、Mybatis中使用JSR310的正确姿势

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

  7. java8新特性_Java8新特性之Date API|乐字节

    大家好,我是乐字节的小乐,上篇文章讲述了<Java8新特性之Optional>,接下来,小乐将接着讲述Java8新特性之Date API 2019日历 Java8之Date API Jav ...

  8. 【java8新特性】——方法引用(四)

    一.简介 方法引用是java8的新特性之一, 可以直接引用已有Java类或对象的方法或构造器.方法引用与lambda表达式结合使用,可以进一步简化代码. 来看一段简单代码: public static ...

  9. 【java8新特性】——Stream API详解(二)

    一.简介 java8新添加了一个特性:流Stream.Stream让开发者能够以一种声明的方式处理数据源(集合.数组等),它专注于对数据源进行各种高效的聚合操作(aggregate operation ...

最新文章

  1. 开源 java CMS - FreeCMS2.7 移动端首页静态化
  2. 脑电分析系列[MNE-Python-19]| 可视化Evoked数据
  3. 20-思科防火墙:Network Static NAT:网络静态NAT
  4. 小学生眼里的飞鸽传书
  5. 软件工程复习提纲——第十章
  6. python将csv转字典_python – 将CSV数据转换为字典中的列表
  7. 如何安装mysql 8.0.12_基于Windows安装MySQL 8.0.12图文教程
  8. angular4获得焦点事件_深究AngularJS——如何获取input的焦点(自定义指令)
  9. 硬盘安装Windows 7
  10. 读书笔记----10日摘抄整理(03)
  11. 西安电子科技大学计算机考博,西安电子科技大学2017年拟录取申请考核博士生名.PDF...
  12. php做网站需要的技术,建网站需要什么技术
  13. Vue传递参数不在URL路径上 显示参数的完整方法
  14. smallpt: Global Illumination in 99 lines of C++讲解
  15. android_驱动_qcom_【高通SDM660平台】(4) --- Camera Init 初始化流程
  16. 使用opencv的透视变换裁剪倾斜人脸
  17. 信息系统面临的安全威胁
  18. 【C++Primer笔记】第四章 表达式
  19. Skype for Symbian
  20. 怎么用生活照制作一寸证件照片

热门文章

  1. phpcms医院wap手机网站模板下载
  2. lldp协议代码阅读_LLDP(链路层发现协议)和OpenFlow
  3. 从小听到大的经典老歌 经典得不可复制
  4. 微型计算机lenovo D5050,联想D5050win10改win7bios设置图文详解
  5. 奶奶版ChatGPT炸了!背刺微软泄露Win11秘钥!
  6. 【图片新闻】据称俄罗斯核动力巡航导弹研制疑似遭遇挫折
  7. 趣味MySQL:查询NBA球员的冠军总数
  8. 大数据对房地产行业的未来发展产生的巨大作用
  9. hdmi网线延长器_什么是HDMI网线延长器?浅析HDMI1.3网线延长器原理和应用
  10. spool命令的使用