Optional容器类——Java8新特性

399 篇文章 12 订阅
package com.example.demo.lambdaOptional;

import com.example.demo.lambda.Employee;
import org.junit.Test;

import java.util.Optional;

/**
 * @Description
 * Optional<T>
 * 	(java.util.Optional)
 *
 * Optional 容器类:用于尽量避免空指针异常
 *  1. 是一个容器类,代表一个值存在或不存在。
 *  2. 原来用null表示一个值不存在,现在Optional可以更好的表达这个概念。
 *  3. 并且可以避免空指针异常。
 *
 * Optional.of(T t) :          创建一个 Optional 实例
 * Optional.empty() :          创建一个空的 Optional 实例
 * T get() :                   如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException
 * Optional.ofNullable(T t):   若 t 不为 null,创建 Optional 实例,否则创建空实例
 * isPresent() :               判断是否包含值
 * orElse(T t) :               如果调用对象包含值,返回该值,否则返回t
 * orElseGet(Supplier s) :     如果调用对象包含值,返回该值,否则返回 s 获取的值
 * map(Function f):            如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
 * flatMap(Function mapper):   与 map 类似,要求返回值必须是Optional
 *
 * @Auther gf.x
 * @Date 2020/3/30 14:35
 */
public class OptionalTest {

    //map(Function f) 方法
    @Test
    public void test5() {
        //Optional<Employee> optional = Optional.ofNullable(new Employee("张三", 18, 9999.99, Employee.Status.FREE));
        Optional<Employee> optional = Optional.of(new Employee("张三", 18, 9999.99, Employee.Status.FREE));

        Optional<String> s = optional.map(Employee::getName);
        System.out.println(s.get()); //在使用get()时,一般要使用isPresent()验证 防止发生异常

        //相比与map,flatMap使用optional对值进行了封装 避免空指针异常
        Optional<String> op3 = optional.flatMap((e) -> Optional.of(e.getName()));
        System.out.println(op3.get());
    }

    //isPresent()、orElse(T t) 方法
    //orElse(T t) : 如果optional包含值则返回,否则定义个默认值返回
    @Test
    public void test3() {
        //Optional<Employee> optional = Optional.ofNullable(new Employee());
        Optional<Employee> optional = Optional.ofNullable(null);

        if (optional.isPresent()) {
            System.out.println(optional.get());
        }
    }

    @Test
    public void test4() {
        //Optional<Employee> optional = Optional.ofNullable(new Employee());
        Optional<Employee> optional = Optional.ofNullable(null);

        Employee employee = optional.orElse(new Employee("张三", 18, 9999.99, Employee.Status.FREE));
        System.out.println(employee);

        //orElseGet(Supplier s) 和 orElse(T t) 相比更灵活一些,orElseGet()方法里面是函数式接口
        Employee employee1 = optional.orElseGet(Employee::new);
        System.out.println(employee1);
    }

    //Optional.ofNullable(T t) 方法
    @Test
    public void test2() {
        //Optional<Employee> optional = Optional.ofNullable(new Employee());

        /*
        Optional.ofNullable()的值可以为null,但get()时会报NoSuchElementException异常
        通过查看Optional.ofNullable()方法源码:
        return value == null ? empty() : of(value)
        可知此方法是 of() 和 empty() 方法的综合。
        */
        Optional<Employee> optional = Optional.ofNullable(null);

        Employee employee = optional.get();
        System.out.println(employee);
    }

    //Optional.empty() 方法
    @Test
    public void test1() {
        Optional<Object> emptyOptional = Optional.empty();

        //由于Optional是空的,所以在get()时会报NoSuchElementException异常
        //但此时也不会报空指针异常
        Object o = emptyOptional.get();

        System.out.println(o);
    }

    //Optional.of(T t) 方法
    @Test
    public void test() {
        Optional<Employee> optional = Optional.of(new Employee());

        //Optional.of()的值不能是null,否则optional.get()时就会报空指针异常
        //Optional<Employee> optional = Optional.of(null);

        Employee employee = optional.get();
        System.out.println(employee);
    }


    /**
     * Optional 实战应用
     * 需求:获取一个男人心中女神的名字
     */

    @Test
    public void test6() {
        //Man man = new Man(new Godness("宋慧乔"));
        Man man = new Man();

        String godnessName = getGodnessName(man);
        System.out.println(godnessName);
    }

    //不使用Optional容器类
    /**
     * 像下面这个方法,由于业务逻辑需要,必须要进行多层if/if else嵌套;
     * 这样的话代码的可读性就降低了很多;
     * 此时我们一般可以逻辑反过来写,先判断 == null 的时候,这样就避免了if else的多层嵌套问题
     */
    public String getGodnessName(Man man) {
        if (man != null) {
            Godness god = man.getGod();
            if (god != null) {
                return god.getName();
            }
        }

        return "林允儿";
    }

    //使用Optional的实体类
    @Test
    public void test7(){
        //Optional<Godness> godness = Optional.ofNullable(new Godness("林允儿"));
        //Optional<NewMan> op = Optional.ofNullable(new NewMan(godness));

        Optional<NewMan> op = Optional.ofNullable(null);
        String name = getGodnessName1(op);
        System.out.println(name);
    }

    public String getGodnessName1(Optional<NewMan> newMan) {

        return newMan.orElse(new NewMan())
                     .getGodness()
                     .orElse(new Godness("宋慧乔"))
                     .getName();
    }
}
package com.example.demo.lambdaOptional;

public class Godness {

	private String name;

	public Godness() {
	}

	public Godness(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Godness [name=" + name + "]";
	}

}
package com.example.demo.lambdaOptional;

public class Man {

	private Godness god;

	public Man() {
	}

	public Man(Godness god) {
		this.god = god;
	}

	public Godness getGod() {
		return god;
	}

	public void setGod(Godness god) {
		this.god = god;
	}

	@Override
	public String toString() {
		return "Man [god=" + god + "]";
	}

}
package com.example.demo.lambdaOptional;

import java.util.Optional;

public class NewMan {

    /**
     * Optional 的使用场景是:
     *      当某个变量/对象的值可能是null,也可能不是null时;
     *      这时我们就需要把它封装到Optional中,进而避免发生空指针异常。
     */

    //不能这样写,这样写Optional<Godness> godness的值就是null
    //private Optional<Godness> godness;

    //把Godness包装/封装到Optional里面
    private Optional<Godness> godness = Optional.empty();

    public NewMan() {
    }

    public NewMan(Optional<Godness> godness) {
        this.godness = godness;
    }

    public Optional<Godness> getGodness() {
        return godness;
    }

    public void setGodness(Optional<Godness> godness) {
        this.godness = godness;
    }

    @Override
    public String toString() {
        return "NewMan{" +
                "godness=" + godness +
                '}';
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值