【Java8】Optional

Optional

Optional简述

按照字面意思的理解,应该可选的意思。一开始我还以为是类似python里面的默认参数用法呢,结果语义是指某个值可能有也可能没有(null)。
感觉名字取得不是很直观。。我觉得叫Nullable不是更好?

python:

def fn(a=‘default_value‘):
    print(a)
    pass

Optional方法

Optional没有公开的构造方法,只有静态工厂方法:

Optional<String> optional_2 = Optional.of(str); // 如果str == null,抛出错误NullPointerException
Optional<String> optional = Optional.ofNullable(str); // 如果str == null,返回一个空Optional<String>
Optional.<String>empty(); // 返回一个空Optional<String>

String s = optional.get(); //获取被包装的值
optional.ifPresent((value) -> System.out.println("hello")); // 如果optional的value不是null,则执行函数表达式

optional.orElse("elseValue"); // 如果optional的value为null,则返回"elseValue"
optional.orElseGet(() -> "orElseGet"); // 如果optional的value不是null,则返回函数表达式的执行结果
optional.orElseThrow(RuntimeException::new); // 如果optional的value不是null,则抛出错误

optional.filter((value) -> value.length() == 5); // 过滤得到长度等于5的value

 optional.map((value) -> {
    System.out.println("map:" + value);
    return value;
});

optional.flatMap((value) -> {
    System.out.println("flatMap:" + value);
    return Optional.ofNullable(value);
});

map 与 flatMap 的区别

map(mapper) 与 flatMap(mapper) 功能上基本是一样的,只是最后的返回值不一样。map(mapper)方法里面的mapper可以返回任意类型,但是flatMap(mapper)方法里面的只能返回Optional类型。

如果mapper返回结果result的不是null,那么map就会返回一个Optional,但是 flatMap 不会对result进行任何包装。一个常见的例子:

Optional<String> os;
os.map((value)->Optional.of(value)) //返回的类型是Optional<Optional<String>>
os.flatMap((value)->Optional.of(value)) //返回的类型是Optional<String>

Optional的好处

  1. 显式的提醒你需要关注null的情况,对程序员是一种字面上的约束

  2. 将平时的一些显式的防御性检测给标准化了,并提供一些可串联操作
  3. 解决一下null会导致疑惑的概念,比如Map里面的key==null的情况,以及value==null的情况

小节

不过Optional一下子有这么多方法,Optional的初衷是什么?而且Optional也是一个对象,所以它本身也有可能是null,这可如何是好。

所以,有个观点认为,Optional比较适用的地方是作为返回值,这样可以给使用者一个善意的提醒。

参考

  1. http://www.javacodegeeks.com/2013/09/deep-dive-into-optional-class-api-in-java-8.html
  2. What‘s the point of Guava‘s Optional class
  3. http://www.nurkiewicz.com/2013/08/optional-in-java-8-cheat-sheet.html
时间: 2024-10-17 01:36:03

【Java8】Optional的相关文章

【java8】慎用java8的foreach循环

虽然java8出来很久了,但是之前用的一直也不多,最近正好学习了java8,推荐一本书还是不错的<写给大忙人看的javase8>.因为学习了Java8,所以只要能用到的地方都会去用,尤其是Java8的Stream,感觉用起来觉得很方便,因为点点点就出来了,而且代码那么简洁.现在开始慢慢深入了解java8,发现很多东西不能看表面. 比如常规遍历一个集合,下面给出例子: 1.首先遍历一个List 方式1.一开始是这样的: public static void test1(List<Strin

【java8】为java8的foreach正名

首先为自己没有经过严格测试得出的错误结论感到抱歉,原博文,测试完感觉自己发现了一个新bug,后来思前想后觉得不应该是这样的,如果效率差的这么多,jdk的开发人员会不去优化它吗,但是怎么重复测试任然得到一样的结果,非常疑惑. 我觉得应该是测试方法出问题了,可是怎么也想不到原因,后来了解到jmh,深入研究了一番,觉得jmh的测试值得借鉴,jmh在测试的时候都会先经过预热几遍要测试的代码,示例如下: public static void main(String[] args) throws Runne

【JAVA8】双冒号

现在JDK双冒号是: public class MyTest {     public static void  printValur(String str){         System.out.println("print value : "+str);     }     public static void main(String[] args) {         List<String> al = Arrays.asList("a", &q

【转】Java8初体验(二)Stream语法详解

原文链接 http://ifeve.com/stream/ Java8初体验(二)Stream语法详解 感谢同事[天锦]的投稿.投稿请联系 [email protected]上篇文章Java8初体验(一)lambda表达式语法比较详细的介绍了lambda表达式的方方面面,细心的读者会发现那篇文章的例子中有很多Stream的例子.这些Stream的例子可能让你产生疑惑,本文将会详细讲解Stream的使用方法(不会涉及Stream的原理,因为这个系列的文章还是一个快速学习如何使用的). 1. Str

Java8之Optional类

写在前头 今天再看阿里的Java开发手册,里面异常处理第10条提到这样一个建议. [推荐]防止 NPE ,是程序员的基本修养,注意 NPE 产生的场景:1 ) 返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE.反例: public int f() { return Integer 对象}, 如果为 null ,自动解箱抛 NPE .2 ) 数据库的查询结果可能为 null .3 ) 集合里的元素即使 isNotEmpty ,取出的数据元素也可能为 null

【DATAGUARD】物理dg配置客户端无缝切换--Fast-Start Failover的配置

[DATAGUARD]物理dg配置客户端无缝切换--Fast-Start Failover的配置 一.2.2  实验环境介绍 项目 主库 dg库 db 类型 单实例 单实例 db version 11.2.0.3 11.2.0.3 db 存储 FS type FS type ORACLE_SID oradg11g oradgphy db_name oradg11g oradg11g 主机IP地址: 192.168.59.130 192.168.59.130 OS版本及kernel版本 RHEL6

【OEM】OEM安装维护

[OEM]OEM安装维护 一.1  BLOG文档结构图       一.2  前言部分   一.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① oem安装和维护 ② OEM各种错误解决     Tips:        ① 若文章代码格式有错乱,推荐使用搜狗.QQ或360浏览器,也可以下载pdf格式的文档来查看,pdf文档下载地址:http://yunpan.cn/cdEQedhCs2kFz (提取码:ed

【WindowsPhone】利用反射初始化和添加 SQLite数据库

首先引用命名空间 using System.Reflection 了解一下 Assembly 类 // // 摘要: // 表示一个程序集,它是一个可重用.无版本冲突并且可自我描述的公共语言运行时应用程序构造块. public abstract class Assembly 我们把Model类都约定好放在同一个命名空间下,下面以User类为例: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 u

【DATAGUARD】物理dg配置客户端无缝切换 (八.4)--ora-16652 和 ora-16603错误

[DATAGUARD]物理dg配置客户端无缝切换 (八.4)--ora-16652 和 ora-16603错误 一.1  BLOG文档结构图       一.2  前言部分   一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① Data Guard Broker 的配置 ② Fast-Start Failover 的配置 ③ Oracle DataGuard 之客户端TAF 配置 ④ 使用DGMGRL 来管理数据库