Java8新特性
Java9新特性

Java8 Optional类详解

JDK8中引入的Optional类可以解决空指针异常, 让我们省略繁琐的非空判断。

Optional类就是一个可以为null容器, 或者保存指定类型的数据,或者为null。

 static <T> Optional<T>   empty() 返回一个空的Optional对象
 boolean equals(Object obj) 
 Optional<T> filter(Predicate<? super T> predicate) 如果有值,返回符合predicate条件的Optional对象, 否则返回空的Optional对象
 <U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper) 如果有值,执行mapper映射函数,返回Optional对象, 如果没有值返回空的Optional对象
 T get() 如果值存在返回, 如果不存在抛出异常NoSuchElementException.
 int hashCode() 
 void ifPresent(Consumer<? super T> consumer) 如果值存在就执行consumer函数,否则什么也不做
 boolean isPresent() 判断值是否存在
 <U> Optional<U> map(Function<? super T,? extends U> mapper) 如果值存在就执行mapper映射函数,
 static <T> Optional<T> of(T value) 把指定的value值封装为Optional对象,如果value为null,产生空指针异常
 static <T> Optional<T> ofNullable(T value) 把指定的value值封装为Optional对象,如果value为null返回一个空的Optional对象
 T orElse(T other) 如果值存在就返回,如果不存在返回other
 T orElseGet(Supplier<? extends T> other) 如果存在就返回值,如果不存在,执行Supplier返回另外一个值
 <X extends  Throwable>     T                orElseThrow(Supplier<? extends X> exceptionSupplier) 如果存在就返回该值,如果不存在抛出由exceptionSupplier生成的异常
 String toString() 
package com.wkcto.optional;

import java.util.Optional;

/**
 * 演示Optional的基本操作
 * Author : 乐学网老崔
 */
public class Test01 {
    public static void main(String[] args) {
        //1)把一个字符串封装为Optional对象
        Optional<String> ofString = Optional.of("wkcto");   //参数不能为null

        //2)为指定的值创建Optional对象,如果参数为null,返回空的Optional对象
        Optional<String> ofString2 = Optional.ofNullable(null);     //参数可以为null
        System.out.println(ofString2);      //Optional.empty

        //3)直接创建一个空的Optional对象
        Optional<String>  ofString3 = Optional.empty();
        System.out.println( ofString3 );

        //4)get() 获得Optional对象中的值,如果值不存在会产生异常
        String  text = ofString.get();
        System.out.println(text);       //wkcto
//        text = ofString2.get();         //java.util.NoSuchElementException

        //5)orElse(),如果Optional对象中有值就返回,没有则返回指定的其他值
        text = ofString.orElse("another");
        System.out.println( text );         //wkcto
        text = ofString2.orElse("another");
        System.out.println( text );     //another

        //6)orElseGet(),如果有值就返回,如果Optional对象中没值则创建一个新的
        text = ofString2.orElseGet(() -> "newString");
        System.out.println( text );     //newString

        //7)orElseThrow(),如果值存在就返回,否则抛出异常
//        text = ofString2.orElseThrow(NullPointerException::new);
        text = ofString.orElseThrow(NullPointerException::new);
        System.out.println( text );

        //8)filter(),如果Optional对象有值返回满足指定条件的Optional对象, 否则返回空的Optional对象
        text = ofString.filter(s -> s.length() > 10).orElse("lenth is letter than 10");
        System.out.println( text );
        text = ofString.filter(s -> s.length() > 3).orElse("lenth is letter than 3");
        System.out.println( text );

        //9) map() 如果Optional对象的值存在,执行mapper映射函数

        text = ofString.map(x -> x.toUpperCase()).orElse("Failure");
        System.out.println( text );         //WKCTO

        text = ofString2.map(x -> x.toUpperCase()).orElse("Failure");
        System.out.println( text );         //Failure

        //10)ifPresent() 如果Optional对象有值就执行Consumer函数
        ofString.ifPresent(s -> System.out.println("处理数据" + s));
        ofString2.ifPresent(s -> System.out.println("处理数据" + s));       //没有值什么也不做
        System.out.println("optional");
    }
}

Optional示例1

package com.wkcto.optional;

import javax.print.attribute.standard.NumberUp;
import javax.sound.midi.Soundbank;
import java.util.Optional;

/**
 * Optional练习1
 * Author : 乐学网老崔
 */
public class Test02 {
    public static void main(String[] args) {
        Address address = new Address("Beijing", "大族企业湾");
//        User user = new User("laocui", address);
//        User user = new User();
        User user = null;

        System.out.println( getName1(user));
        System.out.println( getName2(user));
        System.out.println( getCity1(user));
        System.out.println( getCity2(user));

    }
    //定义方法返回指定用户的用户名 ,如果用户名不存在返回unknown
    public  static  String getName1( User user){
        if ( user == null ){        //判断参数接收的User对象是否为null
            return "unknown";
        }
        return  user.name;
    }
    //Optional可以解决空指针问题
    public  static  String getName2(User user){
        return Optional.ofNullable(user)     //把参数接收的user对象包装为Optional对象
                .map(u -> u.name)           //映射,只需要用户名
                .orElse("unknown");         //存在就返回,不存在返回unknown
    }
    //定义方法返回指定用户的城市
    public static  String getCity1(User user){
        if ( user != null){
            if (user.address != null){
                return user.address.city;
            }
        }
        return "unkown";
    }
    //使用Optional返回用户的城市
    public static  String getCity2(User user){
        return Optional.ofNullable(user)        //把参数对象包装为Optional对象
                .map(u -> u.address)            //映射用户的地址
                .map(addr -> addr.city)         //映射地址的城市
                .orElse("Unkown");              //有就返回,没有返回Unknown

    }
}

//定义用户类
class  User{
    String name;
    Address address;

    public User(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    public User() {
    }
}
//定义地址类
class Address{
    String city;
    String house;

    public Address(String city, String house) {
        this.city = city;
        this.house = house;
    }
}

Optional在实际开发中的应用

package com.wkcto.optionalapp2;

import java.util.Optional;

/**
 * 每个人可能有一部车,每辆车可能都有保险,每个保险公司都有自己的名称
 * Author : 乐学网老崔
 */
public class Test {
    public static void main(String[] args) {
        //1)创建保险对象
        Insurance in1 = new Insurance();
        in1.setName("pingan");
        Optional<Insurance> insurance1 = Optional.ofNullable(in1);  //有保险
        Optional<Insurance> insurance2 = Optional.ofNullable(null);   //保险为null

        //2)创建小汽车对象
        Car car1 = new Car("Geely", insurance1);        //Geely汽车有保险
        Car car2 = new Car("Haval", insurance2);        //Haval汽车没有保险
        Optional<Car> carOptional1 = Optional.ofNullable(car1);     //车有保险
        Optional<Car> carOptional2 = Optional.ofNullable(car2);     //车无保险
        Optional<Car> carOptional3 = Optional.ofNullable(null) ;    //没有车

        //3)创建Person对象
        Person p1 = new Person("lisi", carOptional1);       //lisi有车,有保险
        Person p2 = new Person("wangwu", carOptional2);     //wangwu,有车,没有保险
        Person p3 = new Person("zhaoliu", carOptional3);    //zhaoliu, 没有车

        //4)使用Optional包装Person对象
        Optional<Person> person1 = Optional.ofNullable(p1);     //有车,有保险
        Optional<Person> person2 = Optional.ofNullable(p2);     //有车,没有保险
        Optional<Person> person3 = Optional.ofNullable(p3);     //没有车

        //5)获得人的汽车品牌
        System.out.println( person1.map(Person::getCar));   //返回一个Optional<Optional<Car>>类型的数据
        System.out.println( person1.flatMap(Person::getCar));  //Optional<Car>
        System.out.println( person1.flatMap(Person::getCar).map(Car::getBrand).orElse("Unknown"));
        System.out.println( person2.flatMap(Person::getCar).map(Car::getBrand).orElse("Unknown"));
        System.out.println( person3.flatMap(Person::getCar).map(Car::getBrand).orElse("Unknown"));

        //6)获得人的汽车的保险的名称
        System.out.println( person1.flatMap(Person::getCar)
                    .flatMap(Car::getInsurance)
                    .map(Insurance::getName)
                    .orElse("Unknwon"));
        System.out.println( person2.flatMap(Person::getCar)
                    .flatMap(Car::getInsurance)
                    .map(Insurance::getName)
                    .orElse("Unknwon"));
        System.out.println( person3.flatMap(Person::getCar)
                    .flatMap(Car::getInsurance)
                    .map(Insurance::getName)
                    .orElse("Unknwon"));

    }
}

package com.wkcto.optionalapp2;

import java.util.Optional;

/**
 * 定义人类
 * Author : 乐学网老崔
 */
public class Person {
    private String name;
    private Optional<Car> car;      //不确定是否有车

    public Person(String name, Optional<Car> car) {
        this.name = name;
        this.car = car;
    }

    public String getName() {
        return name;
    }

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

    public Optional<Car> getCar() {
        return car;
    }

    public Person setCar(Optional<Car> car) {
        this.car = car;
        return this;
    }
}
package com.wkcto.optionalapp2;

import java.util.Optional;

/**
 * 汽车类
 * Author : 乐学网老崔
 */
public class Car {
    private String brand;       //汽车品牌
    private Optional<Insurance>  insurance;         //不能确定每辆汽车都有保险

    public Car(String brand, Optional<Insurance> insurance) {
        this.brand = brand;
        this.insurance = insurance;
    }

    public String getBrand() {
        return brand;
    }

    public Car setBrand(String brand) {
        this.brand = brand;
        return this;
    }

    public Optional<Insurance> getInsurance() {
        return insurance;
    }

    public Car setInsurance(Optional<Insurance> insurance) {
        this.insurance = insurance;
        return this;
    }
}
package com.wkcto.optionalapp2;

/**
 * 保险类
 * Author : 乐学网老崔
 */
public class Insurance {
    private  String name;

    public String getName() {

        return name;
    }

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