博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用Java 8 Optional 来进行null处理
阅读量:4221 次
发布时间:2019-05-26

本文共 4478 字,大约阅读时间需要 14 分钟。

引入一个新的类java.util.Optional<T>,这个类封装了Optional的值。

问题:什么时候要用Optional包裹字段,什么不应该用?

(1)应该用Optional的情况:当你认为这个字段可能为null,也可能部位null,或者你自己也不确定的情况。比如:一个人可能有车,也可能没有车,此时,你就应该用一个Optional类来包装,当值为null时对应的就是一个空的Optional对象。

(2)无需Optional的情况:就是你已经明确的知道,某个字段一定不为null,则无需用Optional。

代码如下:

class Person{    private Car car;    public Optional
getCar(){ return Optional.ofNullable(car); } public void setCar(Car car) { this.car = car; }}class Car{ private Insurance insurance; public Optional
getInsurance(){ return Optional.ofNullable(insurance); } public void setInsurance(Insurance insurance) { this.insurance = insurance; }}class Insurance{ private String name; public String getName(){ return name; }}public class NullException { public static String getCarInsuranceName(Optional
person){ return person.flatMap(p->p.getCar()) .flatMap(car->car.getInsurance()) .map(insurance->insurance.getName()) //到这里还是一个Optiona
.orElse("Unkonwn"); } public static void main(String[] args) { Person person = new Person(); //这里person中car字段将为null String carInsuranceName = getCarInsuranceName(Optional.ofNullable(person)); System.out.println(carInsuranceName); }}

输出:

Unkonwn

注意:上述未对字段进行Optional封装,是为了实现序列化,而只是在get相应字段中加入了Optional.

补充:关于Optional实例中的变量值

(1)get方法:(不推荐)如果变量存在(不为null),则直接返回封装的变量值,否则抛出一个NoSuchElementException异常。

(2)orElse(T other):(推荐)其中类型T和Optional<T>中的T是一样的。如果变量存在(不为null),则返回类型为T的变量的值,否则返回T oher。由表达式可知,other是个变量因此,需要预先计算出来。

(3)orElseGet(Supplier<? extends T> other):(推荐)是orElse方法的延迟调用版,Supplier方法只有在Optional对象不含值时(即为null)才执行调用。(这是因为这里传入的是一个行为参数,即lambda表达式)。适用场景是:如果产生默认值耗时比较长可以调用此方法。

(4)orElseThrow(Supplier<? extends X> exceptionSupplier)和get方法非常类似。当Optional对象为空(即为null)时都会抛出一个异常,且这个异常可以是你自己定制的。

(5)ifPresent(Consumer<? super T>)让你能在变量值存在时执行一个作为参数传入的方法,否则就不进行任何操作。该方法返回是void,参数是类似行为参数,也是传入一个lambda表达式。

举几个栗子:

public class TestOptional {    class Person{        private String name;         //绝对不可能为null        private String address;      //有可能为null        private String sex;          //绝对不可能为null        public String getName(){            return name;        }        public void setName(String name){            this.name = name;        }                public Optional
getAddress(){ return Optional.ofNullable(this.address); } public void setAddress(String address){ this.address = address; } public String getSex(){ return sex; } public void setSex(String sex){ this.sex = sex; } } public static void main(String[] args) { //初始化值 TestOptional testOptional = new TestOptional(); TestOptional.Person person = testOptional.new Person(); //这里的new Eclipse不会显示提示,内部类,外部调用比较麻烦点,内部调用还是比较方便 person.setSex("boy"); person.setName("tim"); Optional
address = person.getAddress();// address.get(); String add = address.orElse("default address"); String add2 = address.orElseGet(()->{ return "default address"; }); String add3 = address.orElseThrow(()->{ return new Exception(); }); address.ifPresent((t)->{;}); //这一步只能对对象进行更改,如果是:String或者包装类型以及基本数据类型不起作用 }}

filter代替if语句

public static voidmain(String[] args) {

       //传统的写法

       Room room1 = newRoom("timchen", "525");

       if(room1.getName().equals("timchen")){

           System.out.println("equal" + room1.getName());

       }

       

       //java 8 写法

       Optional<Room> room =Optional.ofNullable(new Room("timchen", "525"));

       room.filter((test)-> "timchen".equals(test.getName())).ifPresent(x->System.out.println("equal" + x.getName()));

    }

可以看到,java8尽量能够少用if语句。如果想对if/else进行改进,在项目中看到很多人可能这么写:

//传统的写法        Room room1 = new Room("timchen", "525");        if(room1.getName().equals("timchen525")){            System.out.println("equal " + room1.getName());        }else{            System.out.println("not equal " + room1.getName());        }                //java 8 写法        Optional
room = Optional.ofNullable(new Room("timchen", "525")); Optional
room2 = room.filter((r)->"timchen525".equals(r.getName())); if(room2.isPresent()){ System.out.println("equal " + room1.getName()); }else{ System.out.println("not equal"); }

可以看到,如果用到if/else语句,可能传统的写法代码更少。

你可能感兴趣的文章
java复习笔记---集合类
查看>>
机器学习入门体验(一)
查看>>
Java的23种设计模式
查看>>
贪心算法实现线段覆盖问题
查看>>
浮点数的二进制表示
查看>>
求一组数字组成的最大整数三种解法
查看>>
廖雪峰Python教程学习笔记(1)
查看>>
关于libsvm在linux下运行时遇到get no rate异常
查看>>
Effective Java 学习笔记一 Object的方法
查看>>
对malloc rolloc calloc的用法以及区别
查看>>
C/C++:long int与long long的区别
查看>>
五种常见软件架构
查看>>
进程间通信的方式——信号、管道、消息队列、共享内存
查看>>
QSQLITE 数据库操作总结
查看>>
Q_OBJECT宏的作用
查看>>
宏Q_OBJECT
查看>>
Qt布局管理(1):部件拉伸原理及大小策略(sizePolicy)
查看>>
Qt 5种标准对话框及使用方法详解
查看>>
Access数据库的存储上限
查看>>
sqlite3数据库最大可以是多大?可以存放多少数据?读写性能怎么样?
查看>>