3.1_27 JavaSE-JDK8新特性 P3 【Optional容器类】处理null值

相关链接



数据准备


通过案例,使用Optional对模拟数据进行一系列处理,熟悉Optional各常用方法

1. pom.xml 配置文件  参考笔记 -> 六、lombok插件

    <dependencies>
       <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
    </dependencies>

2. Employee 实体类

package com.groupies.jdk8.day03.po;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction 员工类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
    private Integer id;
    private String name;
    private Integer age;
    private Double salary;
}

3. OptionalService 服务类,提供初始化数据方法

package com.groupies.jdk8.day03.service;

import com.groupies.jdk8.day03.po.Employee;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class OptionalService {
    /**
     * @return 初始化数据
     */
    public static List<Optional<Employee>> getEmployee() {
        //员工列表
        Employee employee3 = new Employee(null, "张三", 20, 6666.66D);
        Employee employee4 = new Employee(4, "赵四", 26, 3000D);
        Employee employee5 = new Employee(5, "王五", 55, 6000D);

        ArrayList<Optional<Employee>> list = new ArrayList<>();
        list.add(Optional.of(employee3));
        list.add(Optional.of(employee4));
        list.add(Optional.of(employee5));
        return list;
    }
}

1 概述

  Optional<T> 类(java.util.Optional)是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。

  常用方法

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 1 | Optional.of | 创建 Optional 类
静态方法,创建一个 Optional 实例 | T value |Optional<T>
| 2 | Optional.empty | 创建 Optional 类
静态方法,创建一个 Optional 空实例 | - |Optional<T>
| 3 | Optional.ofNullable | 创建 Optional 类
静态方法
1. 入参 T 为null, 创建 Optional 空实例
2. 入参 T 不为null,创建 Optional 实例 | T| Optional<T>
| 4 | get | 获取对象
对于 Optional<T> 对象,通过get方法可以得到 T
其中 T 不能为空,否则会抛出异常 java.util.NoSuchElementException | - | T
| 5 | isPresent | 是否为空
1. 调用对象为null, 返回 false
2. 调用对象不为null,返回 true | - | boolean
| 6 | ifPresent | 安全消费值
1. 调用对象为null, 什么都不做
2. 调用对象不为null,通过Consumer接口(消费型接口)对其进行消费 | Consumer<? extends T> | void
| 7 | orElse | 获取对象/指定值
1. 调用对象为null, 返回 T
2. 调用对象不为null,返回 调用对象

注意: 无论optional是否有值,orElse都会被执行| T| T
Object

| 8 | orElseGet | 获取对象/指定值
1. 调用对象为null, 返回 Supplier提供的返回值
2. 调用对象不为null,返回 调用对象

注意: 只有optional为空时,orElseGet才会被执行| Supplier<? extends T> | T
Supplier提供的返回值
| 9 | orElseThrow | 获取对象/指定值
1. 调用对象为null, 抛出 X 异常
2. 调用对象不为null,返回 调用对象

注意: 只有optional为空时,orElseThrow才会被执行| Supplier<? extends X> throws X|<X extends Throwable> T
| 10 | filter | 过滤
1. Predicate结果为true, 返回调用对象
2. Predicate结果为false,返回Optional.empty()| Predicate<? super T>|Optional<T> 或
Optional.empty();

| 11 | map | 转换
1. 调用对象为null, 返回 Optional.empty()
2. 调用对象不为null,通过Function接口(函数型接口)对其进行处理,返回 Optional<任意值> | Function<? super T, ? extends U> |Optional<U> 或
Optional.empty();

| 12 | flatMap | 转换
1. 调用对象为null, 返回 Optional.empty()
2. 调用对象不为null,通过Function接口(函数型接口)对其进行处理,返回 Optional<任意值> | Function<? super T, Optional<U>> |Optional<U>
map与flatMap的区别:
 1. 请求参数:
  map:  Function接口返回 任意类型 参数。
  flatMap:Function接口返回 Optional类型 参数。
 2. 返回值:
  map:  Function接口返回的参数,再 额外包装一层Optional
  flatMap:Function接口返回参数。
 3. 结论: 简单理解,返回值类型为Optional<T>时使用flatMap,返回值为其他类型时使用map。


2 常用方法


案例1 Optional.of 创建实例

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 1 | Optional.of | 创建 Optional 类
静态方法,创建一个 Optional 实例 | T value |Optional<T>

案例代码一Optional.of 创建实例

package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.of
 */
public class Demo1OptionalOf {
    public static void main(String[] args) {
        Optional<Employee> opt = Optional.of(new Employee());
    }
}

案例2 Optional.empty 创建空实例

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 2 | Optional.empty | 创建 Optional 类
静态方法,创建一个 Optional 空实例 | - |Optional<T>

案例代码二Optional.empty 创建空实例

package com.groupies.jdk8.day03.practice;
import java.util.Optional;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.empty
 */
public class Demo2OptionalEmpty {
    public static void main(String[] args) {
        Optional<Object> opt = Optional.empty();
    }
}

案例3 Optional.ofNullable 有则创建/无则empty()

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 3 | Optional.ofNullable | 创建 Optional 类
静态方法
1. 入参 T 为null, 创建 Optional 空实例
2. 入参 T 不为null,创建 Optional 实例 | T| Optional<T>
案例代码三Optional.ofNullable 有则创建/无则empty()

package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.ofNullable
 */
public class Demo3OptionalOfNullable {
    public static void main(String[] args) {
        //1. 入参 T 为null, 创建 Optional 空实例
        Employee emp1 = null;
        Optional<Object> opt1 = Optional.ofNullable(emp1);
        System.out.println(opt1);//Optional.empty

        //2. 入参 T 不为null,创建 Optional 实例
        Employee emp2 = new Employee();
        Optional<Object> opt2 = Optional.ofNullable(emp2);
        System.out.println(opt2);//Optional[Employee(id=null, name=null, age=null, salary=null)]
    }
}

案例4 get 获取对象

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 4 | get | 获取对象
对于 Optional<T> 对象,通过get方法可以得到 T
其中 T 不能为空,否则会抛出异常 java.util.NoSuchElementException | - | T

案例代码四Optional.get 获取对象

package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.get
 */
public class Demo4OptionalGet {
    public static void main(String[] args) {
		//对于 Optional<T> 对象,通过get方法可以得到 T
        Employee emp1 = new Employee();
        Optional<Object> opt1 = Optional.ofNullable(emp1);
        System.out.println(opt1.get());//Employee(id=null, name=null, age=null, salary=null)

		//其中 T 不能为空,否则会抛出异常 java.util.NoSuchElementException
        Employee emp2 = null;
        Optional<Object> opt2 = Optional.ofNullable(emp2);
        System.out.println(opt2.get());//Exception in thread "main" java.util.NoSuchElementException: No value present
    }
}

案例5 isPresent 是否为空

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 5 | isPresent | 是否为空
1. 调用对象为null, 返回 false
2. 调用对象不为null,返回 true | - | boolean

案例代码五Optional.isPresent 是否为空

package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.isPresent
 */
public class Demo5OptionalIsPresent {
    public static void main(String[] args) {
        //1. 调用对象为null,返回 false
        Optional<Object> opt1 = Optional.empty();
        System.out.println(opt1.isPresent());//false

        //2. 调用对象不为null,返回 true
        Optional<Object> opt2 = Optional.ofNullable(new Employee());
        System.out.println(opt2.isPresent());//true
    }
}

案例6 ifPresent 有则Consumer/无则跳过

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 6 | ifPresent | 安全消费值
1. 调用对象为null, 什么都不做
2. 调用对象不为null,通过Consumer接口(消费型接口)对其进行消费 | Consumer<? extends T> | void
案例代码六Optional.ifPresent 有则Consumer/无则跳过

package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.ifPresent
 */
public class Demo6OptionalIfPresent {
    public static void main(String[] args) {
        //1. 调用对象为null,什么都不做
        Optional<Object> opt1 = Optional.empty();
        opt1.ifPresent(o -> System.out.println(o + " 来消费了"));//

        //2. 调用对象不为null,通过Consumer接口(消费型接口)对其进行消费
        Optional<Object> opt2 = Optional.ofNullable(new Employee());
            //Employee(id=null, name=null, age=null, salary=null) 来消费了
        opt2.ifPresent(o -> System.out.println(o + " 来消费了"));
    }
}

案例7 orElse 有则获取/无则Object

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 7 | orElse | 获取对象/指定值
1. 调用对象为null, 返回 T
2. 调用对象不为null,返回 调用对象

注意: 无论optional是否有值,orElse都会被执行| T| T
Object

案例代码七Optional.orElse 有则获取/无则Object

package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.orElse
 */
public class Demo7OptionalOrElse {
    public static void main(String[] args) {
        //1. 调用对象为null,返回 T
        Optional<Object> opt1 = Optional.empty();
        Object o1 = opt1.orElse(function());
        System.out.println(o1);//function方法执行了:0

        //2. 调用对象不为null,返回 调用对象
        Optional<Object> opt2 = Optional.of(new Employee());
        Object o2 = opt2.orElse(function());
        System.out.println(o2);//function方法执行了:Employee(id=null, name=null, age=null, salary=null)
    
        //3. orElse也可以直接传入Object类型参数
        Object o = opt2.orElse(0);
    }
	
	//注意: 无论optional是否有值,orElse都会被执行
    public static Object function() {
        System.out.print("function方法执行了:");
        return 0;
    }
}

案例8 orElseGet 有则获取/无则Supplier

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 8 | orElseGet | 获取对象/指定值
1. 调用对象为null, 返回 Supplier提供的返回值
2. 调用对象不为null,返回 调用对象

注意: 只有optional为空时,orElseGet才会被执行| Supplier<? extends T> | T
Supplier提供的返回值

案例代码八Optional.orElseGet 有则获取/无则Supplier

package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.orElseGet
 */
public class Demo8OptionalOrElseGet {
    final private static Employee admin = new Employee(0, "Administrator", 0, 0d);

    public static void main(String[] args) {
        //1. 调用对象为null,返回 T
        Optional<Object> opt1 = Optional.empty();
        System.out.println(opt1.orElseGet(() -> {
            System.out.print("Optional对象为空===");
            return admin;
        }));//Optional对象为空===Employee(id=0, name=Administrator, age=0, salary=0.0)

        //2. 调用对象不为null,返回 调用对象
        Optional<Object> opt2 = Optional.of(new Employee());
        System.out.println(opt2.orElseGet(() -> {
            System.out.println("Optional对象为空");
            return admin;
        }));//Employee(id=null, name=null, age=null, salary=null)
    }
}


案例9 orElseThrow 有则获取/无则异常

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 9 | orElseThrow | 获取对象/指定值
1. 调用对象为null, 抛出 X 异常
2. 调用对象不为null,返回 调用对象

注意: 只有optional为空时,orElseThrow才会被执行| Supplier<? extends X> throws X|<X extends Throwable> T
案例代码九Optional.orElseThrow 有则获取/无则异常

package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;
import java.util.function.Supplier;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.orElseThrow
 */
public class Demo9OptionalOrElseThrow {
    public static void main(String[] args) throws Throwable {
        //2. 调用对象不为null,返回 调用对象
        Optional<Object> opt2 = Optional.of(new Employee());
        System.out.println(opt2.orElseThrow((Supplier<Throwable>) () -> {
            System.out.print("orElseThrow方法执行了:");
            return new RuntimeException("Optional对象不能为空");
        }));//Employee(id=null, name=null, age=null, salary=null)

        //1. 调用对象为null,返回 T
        Optional<Object> opt1 = Optional.empty();
        System.out.println(opt1.orElseThrow((Supplier<Throwable>) () -> {
            System.out.print("orElseThrow方法执行了:");
            return new RuntimeException("Optional对象不能为空");
        }));//orElseThrow方法执行了:Exception in thread "main" java.lang.RuntimeException: Optional对象不能为空
    }
}

案例10 filter 过滤

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 10 | filter | 过滤
1. Predicate结果为true, 返回调用对象
2. Predicate结果为false,返回Optional.empty()| Predicate<? super T>|Optional<T> 或
Optional.empty();

需求: 过滤 id不为null 的员工,并打印

处理前:

Optional[Employee(id=null, name=张三, age=20, salary=6666.66)]
Optional[Employee(id=4, name=赵四, age=26, salary=3000.0)]
Optional[Employee(id=5, name=王五, age=55, salary=6000.0)]

处理后:

Optional.empty
Optional[Employee(id=4, name=赵四, age=26, salary=3000.0)]
Optional[Employee(id=5, name=王五, age=55, salary=6000.0)]

案例代码十filter 过滤

package com.groupies.jdk8.day03.practice;

import com.groupies.jdk8.day03.po.Employee;
import com.groupies.jdk8.day03.service.OptionalService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction
 */
public class Demo10OptionalFilter {
    @Autowired
    private static OptionalService optionalService;

    public static void main(String[] args) {
        List<Optional<Employee>> list = optionalService.getEmployee();
        System.out.println("=====处理前=====");
        list.forEach(System.out::println);

        List<Optional<Employee>> collect = list.stream()
                //如果Optional<Employee>中Employee的id为空,则返回Optional.empty
                .map(optional -> optional.filter(employee -> employee.getId() != null))
                .collect(Collectors.toList());

        System.out.println("=====处理后=====");
        collect.forEach(System.out::println);
    }
}

案例11 map 任意类型 转为 Optional

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 11 | map | 转换
1. 调用对象为null, 返回 Optional.empty()
2. 调用对象不为null,通过Function接口(函数型接口)对其进行处理,返回 Optional<任意值> | Function<? super T, ? extends U> |Optional<U> 或
Optional.empty();

案例代码十一Optional.map 任意类型 转为 Optional

package com.groupies.jdk8.day03.practice;
import java.util.Optional;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.map
 */
public class Demo11OptionalMap {
    public static void main(String[] args) {
        Optional<Object> opt = Optional.of("abc");
        Optional<Integer> res1 = opt.map((o) -> 5);
        Optional<Optional<Integer>> res2 = opt.map((o) -> Optional.of(5));
        System.out.println(res1);//Optional[5]
        System.out.println(res2);//Optional[Optional[5]]
    }
}

案例12 flatMap Optional 转为 Optional

|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 12 | flatMap | 转换
1. 调用对象为null, 返回 Optional.empty()
2. 调用对象不为null,通过Function接口(函数型接口)对其进行处理,返回 Optional<任意值> | Function<? super T, Optional<U>> |Optional<U>
案例代码十二Optional.flatMap Optional 转为 Optional

package com.groupies.jdk8.day03.practice;

import java.util.Optional;

/**
 * @author GroupiesM
 * @date 2022/01/12
 * @introduction Optional.filter
 */
public class Demo12OptionalFlatMap {
    public static void main(String[] args) {
        Optional<Object> opt = Optional.of("abc");
        Optional<Integer> res = opt.flatMap((o) -> Optional.of(5));
        System.out.println(res);//Optional[5]
    }
}

22/01/14

M

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值