认识Optional     

Optionals是用于防止 NullPointerException 的漂亮工具。让我们快速了解一下Optionals的工作原理。

Optional 是一个简单的容器,其值可能是null或者不是null。在Java 8之前一般某个函数应该返回非空对象但是有时却什么也没有返回,而在Java 8中,你应该返回 Optional 而不是 null。

        可以大概瞥一眼官方文档:https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

先看几个传统if判空用法:

public static String getName(User u) {
if (u == null || u.name == null)
return "Unknown";
return u.name;
} public static String getChampionName(Competition comp) throws IllegalArgumentException {
if (comp != null) {
CompResult result = comp.getResult();
if (result != null) {
User champion = result.getChampion();
if (champion != null) {
return champion.getName();
}
}
}
throw new IllegalArgumentException("The value of param comp isn't available.");
}
Optional改写:
public static String getName(User u) {
return Optional.ofNullable(u)
.map(user->user.name)
.orElse("Unknown");
} public static String getChampionName(Competition comp) throws IllegalArgumentException {
return Optional.ofNullable(comp)
.map(c->c.getResult())
.map(r->r.getChampion())
.map(u->u.getName())
.orElseThrow(()->new IllegalArgumentException("The value of param comp isn't available."));
}

是不是看着很简洁舒服,可读性也提高了一个档次。

核心常用方法介绍:

如何生成一个Optenal对象?

 Optional<String> s2 = Optional.ofNullable(s);// Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.  

 Optional<Object> empty = Optional.empty();//Returns an empty Optional instance.
//of():为非null的值创建一个Optional
Optional<String> optional = Optional.of("bam");
// isPresent(): 如果值存在返回true,否则返回false
optional.isPresent(); // true
//get():如果Optional有值则将其返回,否则抛出NoSuchElementException
optional.get(); // "bam"
//orElse():如果有值则将其返回,否则返回指定的其它值
optional.orElse("fallback"); // "bam"
//ifPresent():如果Optional实例有值则为其调用consumer,否则不做处理
optional.ifPresent((s) -> System.out.println(s.charAt(0))); // "b"

一般使用Optional.ofNullable(s) 即可 ,返回一个不确定的Optional。

map ()  映射出一个对象放入Optional容器。

 Optional<String> s = Optional.ofNullable(Arrays.asList("1,2,3".split(",")))
.map(li -> li.get(0));
String s3 = Optional.ofNullable(Arrays.asList("1,2,3".split(",")))
.map(li -> li.get(0))
.orElse("4");
.filter()过滤出符合条件的
List<String> list==Optional.ofNullable(Arrays.asList("1,2,3".split(","))) .filter(str->str.equals("2")).orElseThrow(()->new IllegalArgumentException("IllegalArgument"));
Optional.filter() 可以用于参数校验 如:
public void setName(String name) throws IllegalArgumentException {
this.name = Optional.ofNullable(name).filter(User::isNameValid)
.orElseThrow(()->new IllegalArgumentException("Invalid username."));
}

Optional就像一个处理不确定性的管道,我们在一头丢进一个可能是null的东西(接口返回结果),经过层层处理,最后消除不确定性。Optional在过程中保留了不确定性,从而把对null的处理移到了若干次操作的最后,以减少出现NPE错误的可能。

于是,Optional应用的建议也呼之欲出了:

  1. 适用于层级处理(依赖上一步操作)的场合。
  2. 产生对象的方法若可能返回null,可以用Optional包装。
  3. 尽可能延后处理null的时机,在过程中使用Optional保留不确定性。
  4. 尽量避免使用Optional作为字段类型。

这种依赖上一步的操作也叫Continuation。而Optional的这种接受并组合多个Continuation的设计风格就是Continuation-passing style(CPS)。

Java 8 Optional 的用法的更多相关文章

  1. Java 8 Optional 类深度解析

    Java 8 Optional 类深度解析 身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只 ...

  2. Java 8 Optional类使用的实践经验

    前言 Java中空指针异常(NPE)一直是令开发者头疼的问题.Java 8引入了一个新的Optional类,使用该类可以尽可能地防止出现空指针异常. Optional 类是一个可以为null的容器对象 ...

  3. java.util.Optional学习笔记

    java.util.Optional是Java 8新增的类,作为一个持有实例的容器类,可以帮我们把判空的代码写得更优雅,并且该类还提供了一些实用的api,官方文档在这里,接下来我们通过实战来学习吧: ...

  4. Java 8 Optional:优雅地避免 NPE

    本篇文章将详细介绍 Optional 类,以及如何用它消除代码中的 null 检查.在开始之前首先来看下什么是 NPE,以及在 Java 8 之前是如何处理 NPE 问题的. 空指针异常(NullPo ...

  5. Java 8 Optional 良心指南,建议收藏

    想学习,永远都不晚,尤其是针对 Java 8 里面的好东西,Optional 就是其中之一,该类提供了一种用于表示可选值而非空引用的类级别解决方案.作为一名 Java 程序员,我真的是烦透了 Null ...

  6. Java9系列第7篇:Java.util.Optional优化与增强

    我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...

  7. JAVA 8 Optional类介绍及其源码

    什么是Optional对象 Java 8中所谓的Optional对象,即一个容器对象,该对象可以包含一个null或非null值.如果该值不为null,则调用isPresent()方法将返回true,且 ...

  8. java中this的用法?

    2008-07-28 08:10cztx5479 | 分类:JAVA相关 | 浏览4533次 java中this的用法? import java.awt.*; import java.awt.even ...

  9. 转:十八、java中this的用法

    http://blog.csdn.net/liujun13579/article/details/7732443 我知道很多朋友都和我一样:在JAVA程序中似乎经常见到“this”,自己也偶尔用到它, ...

随机推荐

  1. spring boot+Quartz+数据库存储

    SpingBoot+Quartz+数据库存储 1.Spring整合Quartz 2.读取数据库中表达式启动定时任务1(每5s执行) 3.更改定时任务状态(启用/禁用),定时任务1停止 4.读取数据库中 ...

  2. 查vue版本号

    在项目中,找到package.json文件夹 找"dependencies"然后就可以看到你装的vue的版本了.

  3. AnsiString

    原文链接:https://blog.csdn.net/Li_Ning_/article/details/82981092 /* * 编号:Number 1 * 函数:substring * 说明:截取 ...

  4. Vector(动态数组)怎么用咧↓↓↓

    定义方式:vector<int> a; //二维vector<int>a[100] 在末尾压入容器:a.push_back(x);//二维 a[i].push_back(x) ...

  5. 前端如何搭建vue UI组件库/封装插件(从零到有)

    需求 因之前是做外包项目居多,经常用到相同的组件,之前的办法是在一个项目中写一个组件,其他项目直接将compents下的组件复制,粘贴到项目中使用,缺点是维护起来,改一个项目,其他项目也需要修改,所以 ...

  6. 【洛谷】P1032 字串变换

    题目地址:https://www.luogu.org/problemnew/show/P1032 洛谷训练场BFS的训练题呀. “BFS不就是用队列的思想去遍历一切情况嘛.我已经不是小孩子了,我肯定能 ...

  7. iis启动 服务无法在此时接受控制信息。 (异常来自 HRESULT:0x80070425)

    问题描述:每隔一段时间应用程序池就会自动停止. 再次启动就报错:服务无法在此时接受控制信息. (异常来自 HRESULT:0x80070425) 处理办法:同时按下Win+R,运行“services. ...

  8. java.lang.Thread类的静态方法sleep()和yield()的比较

    [线程让步yield()方法] yield()方法可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程从运行状态转入就绪状态. 只是让当前的线程暂停一下,让系统的线程调度器重新调度一次. ...

  9. [C++] 对象指针使用方法

    对象指针:指向类对象的指针 类指针指向类变量(对象)的地址 对象指针定义格式: 类类型 *变量名: 举例: #include <iostream> using namespace std; ...

  10. 第10组 Alpha冲刺(4/6)

    链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 学习调用中国天气网API,接近实现天气推送功能 对天气推送的形式进行讨论及重确 ...