前言

身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法。我们首先要判断这个返回值是否为null,只有在非空的前提下才能将其作为其他方法的参数。这正是一些类似Guava的外部API试图解决的问题。一些JVM编程语言比如Scala、Ceylon等已经将对在核心API中解决了这个问题。

Optional概述

新版本的Java,比如Java 8引入了一个新的Optional类。Optional类的Javadoc描述如下:

这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

本文会逐个探讨Optional类包含的方法,并通过一两个示例展示如何使用。

实例演示

of

为非null的值创建一个Optional。

of方法通过工厂方法创建Optional类。需要注意的是,创建对象时传入的参数不能为null。如果传入参数为null,则抛出NullPointerException 。

ofNullable

为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。

isPresent

如果值存在返回true,否则返回false。

get

如果Optional有值则将其返回,否则抛出NoSuchElementException。

ifPresent

如果Optional实例有值则为其调用consumer,否则不做处理

orElse

如果有值则将其返回,否则返回指定的其它值。

orElseGet

orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值

orElseThrow

如果有值则将其返回,否则抛出supplier接口创建的异常。

在orElseGet方法中,我们传入一个Supplier接口。然而,在orElseThrow中我们可以传入一个lambda表达式或方法,如果值不存在来抛出异常。

map

如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。

map方法用来对Optional实例的值执行一系列操作。通过一组实现了Function接口的lambda表达式传入操作。

flatMap

如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。

flatMap方法与map方法类似,区别在于mapping函数的返回值不同。map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是Optional。

参照map函数,使用flatMap重写的示例如下:

filter

如果有值并且满足断言条件返回包含该值的Optional,否则返回空Optional。

这里可以传入一个lambda表达式。对于filter函数我们应该传入实现了Predicate接口的lambda表达式。

完整示例

/* of */
//调用工厂方法创建Optional实例
Optional<String> name = Optional.of("YanWei");
//传入参数为null,抛出NullPointerException.
//Optional<String> someNull = Optional.of(null); /*opNullable*/
Optional empty = Optional.ofNullable(null); /*isPresent*/
if (name.isPresent()) {
System.out.println(name.get());//输出YanWei
} /*get*/
try {
System.out.println(empty.get());
} catch (NoSuchElementException ex) {
System.err.println(ex.getMessage());
} /*ifPresent*/
name.ifPresent((value) -> {
System.out.println("The length of the value is: " + value.length());
}); /*orElse*/
System.out.println(empty.orElse("There is no value present!"));
System.out.println(name.orElse("There is some value!")); /*orElseGet*/
System.out.println(empty.orElseGet(() -> "Default Value"));
System.out.println(name.orElseGet(String::new)); /*orElseThrow*/
try {
empty.orElseThrow(IllegalArgumentException::new);
} catch (Throwable ex) {
System.out.println("error:" + ex.getMessage());
} /*map*/
Optional<String> upperName = name.map((value) -> value.toUpperCase());
System.out.println(upperName.orElse("No value found")); /*flatMap*/
upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
System.out.println(upperName.get()); /*filter*/
List<String> names = Arrays.asList("YanWei","YanTian");
for(String s:names)
{
Optional<String> nameLenLessThan7 = Optional.of(s).filter((value) -> value.length() < 7);
System.out.println(nameLenLessThan7.orElse("The name is more than 6 characters"));
}

参考

Java8学习笔记(六)--Optional的更多相关文章

  1. Java8学习笔记目录

    Java8学习笔记(一)--Lambda表达式 Java8学习笔记(二)--三个预定义函数接口 Java8学习笔记(三)--方法引入 Java8学习笔记(四)--接口增强 Java8学习笔记(五)-- ...

  2. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  3. Java8学习笔记----Lambda表达式 (转)

    Java8学习笔记----Lambda表达式 天锦 2014-03-24 16:43:30 发表于:ATA之家       本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人 ...

  4. Learning ROS for Robotics Programming Second Edition学习笔记(六) indigo xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  5. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  6. Java8学习笔记(八)--方法引入的补充

    在Java8学习笔记(三)--方法引入中,简要总结了方法引入时的使用规则,但不够完善.这里补充下几种情况: 从形参到实例方法的实参 示例 public class Example { static L ...

  7. python3.4学习笔记(六) 常用快捷键使用技巧,持续更新

    python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...

  8. Go语言学习笔记六: 循环语句

    Go语言学习笔记六: 循环语句 今天学了一个格式化代码的命令:gofmt -w chapter6.go for循环 for循环有3种形式: for init; condition; increment ...

  9. 【opencv学习笔记六】图像的ROI区域选择与复制

    图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...

  10. Linux学习笔记(六) 进程管理

    1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...

随机推荐

  1. Cocos2dx使用TextField实现输入框

    游戏login的时候必须要求玩家输入用户名.密码,还要可以删除. cocostudio画一个textfield,直接读入好了: textField类,继承读取的widget. local textFi ...

  2. java计算今天是今年的第几天

    Calendar.getInstance().get(Calendar.DAY_OF_YEAR)

  3. [原创]H5前端性能测试工具介绍

    [原创H5前端性能测试工具介绍 一 网络抓包工具 网络抓包工具选择原则,可以捕获网络请求,抓取具体请求信息流,同时可以针对网络请包进行修改或拦截: 1.Fiddler(推荐) 2.Charles(推荐 ...

  4. IAAS、SAAS 和 PAAS 的区别、理解

    通俗的讲: 如果你是一个网站站长,想要建立一个网站.不采用云服务,你所需要的投入大概是:买服务器,安装服务器软件,编写网站程序.现在你追随潮流,采用流行的云计算,如果你采用IaaS服务,那么意味着你就 ...

  5. 动态ip、静态ip、pppoe拨号的区别

    pppoe拨号 pppoe拨号上网,又叫做ADSL拨号上网.宽带拨号上网.指现在有很多我的E家用户,送的无线猫,阉割了PPPOE拨号功能,必须要从电脑上拨号才能上网.还有大街上的WIFI热点也很多,如 ...

  6. Java SPI机制学习笔记

    最近在阅读框架源代码时,常常看到 SPI 的子包, 忍不住查了下: Service Provider Interface : 服务提供接口. JavaSPI 实际上是“基于接口的编程+策略模式+配置文 ...

  7. tensorflow之数据读取探究(1)

    Tensorflow中之前主要用的数据读取方式主要有: 建立placeholder,然后使用feed_dict将数据feed进placeholder进行使用.使用这种方法十分灵活,可以一下子将所有数据 ...

  8. Neo4j(一)

    01-windows下载与安装neo4j https://blog.csdn.net/qq_21383435/article/details/78807024 neo4j的配置文件(图文详解) htt ...

  9. Centos7安装Tomcat并部署DubboAdmin的War包并配置自动启动

    一.安装过程 1.打开官网,在左侧选择要下载的版本,比如下下载Tomcat8:https://tomcat.apache.org/download-80.cgi 2.找到tar.gz的下载地址:htt ...

  10. 从网上找的Android实用代码,记录备用

    1.获取应用程序下所有Activity public static ArrayList<String> getActivities(Context ctx) { ArrayList< ...