Guava-Optional可空类型

接上篇Guava之Joiner和Splitter,本篇将介绍Guava的另外一个有用的对象Optional,这在Java中Google Guava首先给我们提出可空对象模型的。在其他语言如c#这是已经存在很久的模式,并包含在.net类库中Nullable(Int?也是一个可空类 型)。

Null sucks

回到本文主题Optional。在我日常编程中NullPointerException是肯定是大家遇见最多的异常错误:

为此Doug Lea曾说过:

Null sucks.

Sir C. A. R. Hoare也曾说过:

I call it my billion-dollar mistake.

从上面我们能够足以看出NullPointerExceptiond的出现频率和可恨之处。因此在GOF的设计模式中我们也专门提出了空对象模式(或称特例模式)来应对这可恶的NullPointerExceptiond。空对象模式主要以返回一些 无意义并不影响处理逻辑的特定对象来替代null对象 ,从而避免没必要的null对象的判断。 例如在计算一组员工的总共薪资的时候,对于返回的null对象则我们可以返回默认值为了 0 薪资的员工对象,那么我们就不需要做任何null的判断。

员工薪资问题

那么在Guava的Optional又该怎么解决呢?在讲解Optional之前,让我们仍然以计算一组员工的总共薪资为例用原生java代码将来看看:

 
@Test
public void should_get_total_age_for_all_employees() throws Exception {
    final List<Employee> list = Lists.newArrayList(new Employee("em1", 30), new Employee("em2", 40), null, new Employee("em4", 18));
    int sum = 0;
    for (Employee employee : list) {
        if (employee != null) {
            sum += employee.getAge();
        }
    }
    System.out.println(sum);
}
private class Employee {
    private final String name;
    private final int age;
    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
}

如果换成Guava Optional将如何:

 
 @Test
public void should_get_total_age_for_all_employees() throws Exception {
    final List<Employee> list = Lists.newArrayList(new Employee("em1", 30),
        new Employee("em2", 40),
         null,
         new Employee("em4", 18));
    int sum = 0;
    for (Employee employee : list) {
        sum += Optional.fromNullable(employee).or(new Employee("dummy", 0)).getAge();
    }
    System.out.println(sum);
}

从上面可以清晰看出,我们不在担心对象对空了,利用Optional的fromNullable创建了一个可空对象,并将其or上一个dummy的员工信息,所以在这里我们不在担心NullPointerExceptiond。

也许你会说和利用三目运算 ( _ ? :_)没什么差别,在此例子中功能是的确是没多大差距,但是个人觉得Guava更有语义,更通用一些,而且满足很多空对象模式使用的场景。

Optional API

*. OptionalObject.isPresent(): 返回对象是否有值。

*. Optional.absent(): 返回一个空Optional对象,isPresent() 将会返回false

*. Optional.of(): 创Optional对象,输入参数不能为null

*. Optional.fromNullable(): 创Optional对象,输入可以为null

*. OptionalObject.asSet(): 和Optional对象值合并,如果为null则返回size为0的Set

*. OptionalObject.or(): 和Optional对象值合并,如果为null为空加则返回or参数作为默认值

*. OptionalObject.orNull(): 和Optional对象值合并,如果为null为空加则返回Null作为默认值

上面的api都是我们在使用Optional的时候最常用的方法属性方法,注意如果我们创建了Optional对象,但是没有判断isPresent()是否存在,就直接get这是会抛异常的,这属于乱用Optional情况,和直接用Null并没什么差别。

 
final Optional<Object> obj = Optional.fromNullable(null);
final Object o = obj.get();

同样Optional为空对象模式,可以添加默认值,null不会影响我们的处理,如果为null我们无法继续程序处理的情况,需要抛异常 或者中断的的,还是需要抛异常、中断,利用Preconditions.checkNotNull等,而不是继续套一层Optional对象,这也属于乱 用Optional之列。

时间: 2024-07-30 10:13:45

Guava-Optional可空类型的相关文章

03 php 数据类型:整数,进制转换,浮点,字符,布尔,数组,空类型,类型转换,算术运算,比较运算

03 数据类型:整数,进制转换,浮点,字符,布尔,数组,空类型,类型转换, 算术运算,比较运算,逻辑运算,短路现象, 三目运算符,字符型运算: 数据类型 整体划分 标量类型: int, float, string, bool 复合类型: array,     object 特殊类型: null,     resouce 整数类型int, integer 3种整数表示法 十进制写法:123: $n1 = 123; 八进制写法: 0123 $n2 = 0123; 十六进制写法: 0x123 $n3

Kotlin---------------可空类型与? ?: ?. !!

可空类型主要是为了从编译层面尽可能的减少NPE. 在Kotlin中申明一个变量,如果类型后面不加?则不能直接给此变量赋值为null,在类型后面加上?就变成了可空类型,而可空类型可以直接赋值为null var name: String = null//Error:Null can not be a value of a non-null type String var name1: String? = null//可空类型,可以赋值为null 那么可空类型和普通的类型在使用上有什么区别呢,这就涉及

swift_枚举 | 可为空类型 | 枚举关联值 | 枚举递归 | 树的概念

***************可为空的类型 var demo2 :we_demo = nil 上面这个代码串的语法是错的 为什么呢, 在Swift中,所有的类型定义出来的属性的默认值都不可以是nil 不管是普通简单值类型还是引用类型 那我就是要让这个属性默认值为空,为nil 怎么办呢,很简单,用语法,在定义这个属性的时,在类型后面声明一个? 这样就表示这个属性除了指定类型的默认值外还可以是一个可为空的类型 在Java中,最常见的错误类型就是NullPoinExecption, 为什么就是要有Nu

可空类型

可空类型.匿名方法和迭代器这三个优美的特性是在C#2.0里面提出来的. 1.可空类型 当我们在使用数据库的时候,会发现这样的一个矛盾点:数据库的字段设置是允许为null的,比如日期的字段,当你想把数据库表映射为C#中的对象时会发现,DateTime类型在C#语言中是不能为null的! 1.1 简介 可空类型也是值类型,但它是包含null值的值类型:int? nullable=null; int?就是可空的int类型.很明显,这又是一个语法糖,肯定不会存在int?这样的类型.对于编译器而言,int

C# 可空类型

可以为null的类型赋其基础类型正常范围的值和null值. 例如:Nullable<Int32>可以赋值为-2147483618到2147483618之间任意值和null.(int?=null 或int?=9) 在处理数据库和其他包含可能未赋值的元素的数据类型时,将 null 赋值给数值类型或布尔型的功能特别有用. 例如,数据库中的布尔型字段可以存储值 . 例子说明: using System; namespace CalculatorApplication { class Nullables

C#可空类型的速度和GC Alloc测试

在Unity中进行速度和GC Alloc的测试 测试脚本: using UnityEngine; using System; using System.Collections; using System.Diagnostics; public class NullableTest : MonoBehaviour { void Start() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i

空类型指针(void *)的理解

void指针是空类型指针,它不指向任何类型,即void指针仅仅是一个地址,所以空类型指针不能进行指针运算,也不能进行间接引用(因为指针运算和间接引用都需要指针的类型信息). 例如: void * p; //仅仅表示p存放一个地址 p++; //error:+.-运算离不开指针类型 *p=20.5; //error:访问p指向的变量空间需要变量类型信息 由于其他指针都包含有地址信息,所以将其他指针的值赋给空类型指针是合法的:反之,将空类型指针赋给其他指针则不被允许,除非进行显式转换. 例如: in

【C#】可空类型(Nullable)

C# 可空类型(Nullable) C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值. 例如,Nullable< Int32 >,读作"可空的 Int32",可以被赋值为 -2,147,483,648 到 2,147,483,647 之间的任意值,也可以被赋值为 null 值.类似的,Nullable< bool > 变量可以被赋值为 true 或 false 或 null.

动软Model 模板 生成可空类型字段

动软代码 生成可空类型 <#@ template language="c#" HostSpecific="True" #> <#@ output extension= ".cs" #> <# TableHost host = (TableHost)(Host); host.Fieldlist.Sort(CodeCommon.CompareByintOrder); #> using System; using S