Upgrading to Java 8——第三章 Optional and Similar Classes
Java程序员对付空指针异常已经好多年了。在Java8中将有新的方式去处理他们。通过包装一个潜在的可能为null的类称为Optianal。
在Java8中添加了the Optional, OptionalInt, OptionalLong 和 OptionalDouble 类来处理空指针异常(NullPointerExceptions)。
在java.util的包中,有很多使用Lambda表达式和方法引用的范例类。
这四个类是很相似的,Optional是它们当中最重要的类因为他可以用在任何类型上,其他的类只能各自用在integer,long和double上。
Optional 是一个包含可能会为null的值的容器。你应该认识到,试图去一个null的引用去调用方法或是属性会发生NullPointerException异常。处理空指针异常不是很难,但是很乏味。
考虑下面的代码,一个公司会有一个办公室,进而会有一个地址。为了简单起见,在这里地址有两个属性是街道和城市,这些所有的属性都可能为null。一个公司可能会没有办公室,一个地址可能没有完整的街道和城市的信息。
class Company {
private String name;
private Office office;
public Company(String name, Office office) {
this.name = name;
this.office = office;
}
public String getName() {
return name;
}
public Office getOffice() {
return office;
}
}
class Office {
private String id;
private Address address;
public Office(String id, Address address) {
this.id = id;
this.address = address;
}
public String getId() {
return id;
}
public Address getAddress() {
return address;
}
}
class Address {
private String street;
private String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
public String getStreet() {
return street;
}
public String getCity() {
return city;
}
}
public class OptionalDemo1 {
public static void main(String[] args) {
Address address1 = new Address(null, "New York");
Office office1 = new Office("OF1", address1);
Company company1 = new Company("Door Never Closed", office1);
// What is the street address of company1?
// In which city company1 is located?
String streetAddress = null;
String city = null;
if (company1 != null) {
Office office = company1.getOffice();
if (office != null) {
Address address = office.getAddress();
if (address != null) {
streetAddress = address.getStreet();
city = address.getCity();
}
}
}
System.out.println("Street Name:" + streetAddress);
System.out.println("City:" + city);
}
}
OptionalDemo1类为了测试创建了Company实例去获取公司的街道地址,考虑到所有的属性可能为空,我们在调用方法前都做了非空的处理,就像下面的代码:
if (company1 != null) {
Office office = company1.getOffice();
if (office != null) {
Address address = office.getAddress();
if (address != null) {
streetAddress = address.getStreet();
city = address.getCity();
}
}
}
这种代码既无聊也读起来遭罪。
这个时候Optional能够帮助你,如果你决定用它,你需要把所有可能为null的属性全部用Optional包装起来。例如,Company类中的office属性应该是这样的:
private Optional<Office> office;
Address类中的city属性应该是这样的:
private Optional<String> city;
在重写上面的代码之前,先看下Optional类的一些方法:
| 方法 | 描述 |
| empty | 返回一个空的Optional类 |
| filter | 如果一个值存在并且能供匹配给定的Prdicate接口,则返回Optiaonal描述的值,否则,返回一个空的Optional类 |
| flatMap | 如果值存在,应用指定的映射方法给这个值,返回Optional类描述的映射结果;如果值不存在,则返回一个空的Optional类 |
| get | 如果值存在,则返回该值;否则,抛出NoSuchElementException异常。 |
| ifPresent | 如果值存在,调用指定的Consumer接口用这个值。 |
| isPresent | 如果值存在,返回true;否则,返回false。 |
| map | 如果值存在,给它应用指定的映射方法。如果结果不为null,返回一个Optional类的描述结果。 |
| of | 返回一个Optional描述的不为null的值。 |
| ofNullable | 如果给定的值不为null,返回Optional描述的值,如果为null,返回空的Optional类。 |
| orElse | 如果值存在,返回该值,否则返回指定的值。 |
这些方法很容易使用,把一个值包装在Optional类中,调用它的静态方法or或orNullable。如果你确定你包装的值不为null就用of方法。如果值可能潜在存在null就用ofNullable方法。相应的,empty静态方法返回一个空的Optional类,例如,一个没有值的Optional类。
剩下的方法就来对Optional的处理。如果你想简单的检索一个值在Optional中,首先检查一个值是否存在,你可以使用isPresent 方法然后接着使用get方法。
if (optional.isPresent()) {
value = optional.get();
}
不管怎样,这很类似跟不用Optional处理null的情况,但这是个更好的方式。
ifPresent方法接收一个Consumer函数式接口如果值存在的话会被调用,所以,如果想简单打印值,可以这样:
optional.ifPresent(System.out::println);
如果值存在,则什么都不会发生。
flatMapfang方法应用一个映射方法并返回一个Optional描述的值,不止这些,它可以被级联调用,像下面这样检查以系列的null的情况:
company1.flatMap(Company::getOffice)
.flatMap(Office::getAddress)
.flatMap(Address::getCity)
.ifPresent(System.out::println);
现在,我们用Optional类来重写OptionalDemo2类。
OptionalInt, OptionalLong and OptionalDouble 有Optional的子集的方法。他们都有empty, ifPresent, isPresent, of需要一个原始类型。因为原始类型不能是null,所以没有ofNullable和get方法。取代的,OptionalInt有getAstInt方法,OptionalLong有getAsLong方法,OptiaonalDouble有getAsDouble方法。他们没有filter,flatMap和map方法。
Upgrading to Java 8——第三章 Optional and Similar Classes的更多相关文章
- java基础(三章)
java基础(三章) 一.基本if结构 1.流程图 l 输入输出 l 判断和分支 l 流程线 1.1 简单的if条件判断 if(表达式){ //表 ...
- “全栈2019”Java多线程第三章:创建多线程之实现Runnable接口
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java异常第三章:try代码块作用域详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- 20165233 Java第二、三章学习总结
2017-2018-2 <Java程序设计>第二周学习总结 教材学习内容总结 第二.三章 ch2 标识符与关键字 基本数据类型: 逻辑类型:boolean 整数类型:int.byte.sh ...
- Upgrading to Java 8——第四章 The Stream API
在这章中我们将学习Stream API,在JDK 8 中的一项新的特性.为了理解这一章的主题,你需要知道如何使用Lambda表达式和java.util.function里的预定义的函数式接口. 一个S ...
- <<深入Java虚拟机>>-第三章-垃圾收集器与内存分配策略-学习笔记
垃圾收集 垃圾收集(Garbage Collection,GC),垃圾收集需要完成的三件事情. 哪些对象需要回收 什么时候回收 如何回收 如何确定对象已死(即不可能在被任何途径引用的对象) 引用计数算 ...
- JAVA基础第三章-类与对象、抽象类、接口
业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 我将会持续更新java基础知识,欢迎关注. 往期章节: JAVA基础第一 ...
- Java OOP——第三章 多态
1.多态:(polymorphism): 是具有表现多种形态能力的特征: (专业化的说法:)同一个实现接口(引用类型),使用不同的实例而执行不同的操作 指一个引用(类型)在不同情况下的多种状态.也可以 ...
- 疯狂JAVA讲义第三章之数组篇
package test; /** * Desription: * @author orangebook *<br/>网站:<a href="http://www.cr ...
随机推荐
- N层电梯只停一层情况下,求所有人爬楼层数最少
一.题目: 石家庄铁道大学基础教学楼一共有四部电梯,每层都有人上下,电梯在每一层都停.信1201-1班张一东每层都停有点儿不耐烦.如果在上下课高峰时刻电梯从一层上行,但只允许停留在某一层.每个人选择自 ...
- Date and Time in PeopleCode
Setting a Date to Null in PeopleCode To set a date to null in PeopleCode either use the SetDefault() ...
- 一款jQuery特效编写的大度宽屏焦点图切换特效
一款jQuery编写的大度宽屏焦点图切换特效 焦点图显示区域有固定的宽度,当前显示宽度之外是一个半透明层显示的其它的焦点图片, 最好的是,此特效兼容IE6以及其它浏览器. 适用浏览器:IE6.IE7. ...
- spark概论,补充
基本概念 RDD spark最大的亮点是提出RDD(Resilient Distributed Dataset)的概念,也就是可伸缩的分布式数据集合,本身只读,可恢复.spark本身不做物理储存,通过 ...
- 【转】在delphi中实现控件的拖拽
提示:可以添加一个布尔来控制可否拖动的状态,这里提供所有都能拖动的方法. procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseB ...
- VS活动解决方案平台
测试环境:win7 x64 测试程序:WCF查询数据库后将数据集返回到Winform程序加载并显示 测试结果: 1.从感觉来说Exe在 x86目标平台生成,启动速度快. 2.内存消耗:x86的程序在超 ...
- scrapy爬虫框架入门教程
scrapy安装请参考:安装指南. 我们将使用开放目录项目(dmoz)作为抓取的例子. 这篇入门教程将引导你完成如下任务: 创建一个新的Scrapy项目 定义提取的Item 写一个Spider用来爬行 ...
- 十天学会单片机Day2键盘检测(独立键盘、矩阵键盘)
1.键盘的分类 编码键盘:键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘 非编码键盘:靠软件编程来识别的称为非编码键盘.独立键盘.矩阵键盘 2.按键消抖 ...
- 【C#】 装箱 (boxing) 和拆箱 (unboxing)
目录: 1. 装箱和拆箱 2. 深入理解装箱和拆箱 3. int[] to object[],值类型数组到对象数组的转化 4. 使用泛型减少装箱和拆箱 1. 装箱和拆箱 装箱 就是把“值类型”转换成 ...
- 装黑苹果的那些事儿(以ThinkpadE540为例)
苹果系统,有着比window更好的安全性和方便性,更重要的事,没有MAC系统环境,进行iOS开发,是很麻烦的,对新手来说,是很懊恼的一件事.但是白苹果像件奢侈品,吾等常人,很难有经济消费.如是黑苹果是 ...