JAVASE学习笔记(十五)(Optional的应用)

JAVASE学习笔记(十五)(Optional的应用),第1张

JAVASE学习笔记(十五)(Optional的应用)

JAVASE学习笔记(十五)
  • jdk1.8新特性`Optional`的应用
    • 概述
    • 作用
    • 源码分析
      • 方法
        • 1. `isPresent`:判断查询的类对象是否存在
        • 2. ` orElseThrow()`: 相当于` if ... throws`
        • 3. `orElse()`:相当于 `if + new (赋值默认值)`
        • 4. `oElseGet()`:相当于 `if + 加逻辑处理`
      • 应用 :`isPresent`和`orElse()`
      • 总结
        • `of` 和`offNullAble`区别
        • `Optional`中`filter` ,`map`,`flatmap`的认识
          • 注意:`filter` ,`map`,`flatmap`都属于`java.util.Stream`的中间方法。但此处的`filter`方法与之前的`stream`流中间方法无关

> 学相伴学习笔记
jdk1.8新特性Optional的应用 概述

Google Guava项目曾提出用Optional类来包装对象从而解决NullPointerException。受此影响,JDK8的类中也引入了Optional类,在新版的SpringData Jpa和Spring Redis Data中都已实现了对该方法的支持。

作用
  • 简化程序逻辑
  • 可以修复程序代码中的逻辑判断的问题
源码分析
package java.util;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public final class Optional {
    
    private static final Optional EMPTY = new Optional<>();

    
    private final T value;

    
    private Optional() {
        this.value = null;
    }

    
    public static Optional empty() {
        @SuppressWarnings("unchecked")
        Optional t = (Optional) EMPTY;
        return t;
    }

    
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

    
    public static  Optional of(T value) {
        return new Optional<>(value);
    }

    
    public static  Optional ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

    
    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

    
    public boolean isPresent() {
        return value != null;
    }

    
    public void ifPresent(Consumer consumer) {
        if (value != null)
            consumer.accept(value);
    }

    
    public Optional filter(Predicate predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
    }

    
    public Optional map(Function mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }

    
    public Optional flatMap(Function> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Objects.requireNonNull(mapper.apply(value));
        }
    }

    
    public T orElse(T other) {
        return value != null ? value : other;
    }

    
    public T orElseGet(Supplier other) {
        return value != null ? value : other.get();
    }

    
    public  T orElseThrow(Supplier exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }

    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (!(obj instanceof Optional)) {
            return false;
        }

        Optional other = (Optional) obj;
        return Objects.equals(value, other.value);
    }

    
    @Override
    public int hashCode() {
        return Objects.hashCode(value);
    }

    
    @Override
    public String toString() {
        return value != null
            ? String.format("Optional[%s]", value)
            : "Optional.empty";
    }
}

通过源码分析 ,可以知道Optional是一个final类,

  • 不能被继承
  • 构造函数私有,是单列的对象
  • 提供一系列的方法,对其java程序逻辑的判断和优化处理:
序号方法方法说明1private Optional()无参构造,构造一个空Optional2private Optional(T value)根据传入的非空value构建Optional3public static Optional empty()返回一个空的Optional,该实例的value为空4public static Optional of(T value)根据传入的非空value构建Optional,与Optional(T value)方法作用相同5public static Optional ofNullable(T value)与of(T value)方法不同的是,ofNullable(T value)允许你传入一个空的value,当传入的是空值时其创建一个空Optional,当传入的value非空时,与of()作用相同6public T get()返回Optional的值,如果容器为空,则抛出NoSuchElementException异常7public boolean isPresent()判断当家Optional是否已设置了值8public void ifPresent(Consumer consumer)判断当家Optional是否已设置了值,如果有值,则调用Consumer函数式接口进行处理9public Optional filter(Predicate predicate)如果设置了值,且满足Predicate的判断条件,则返回该Optional,否则返回一个空的Optional10public Optional map(Function mapper)如果Optional设置了value,则调用Function对值进行处理,并返回包含处理后值的Optional,否则返回空Optional11public Optional flatMap(Function> mapper)与map()方法类型,不同的是它的mapper结果已经是一个Optional,不需要再对结果进行包装12public T orElse(T other)如果Optional值不为空,则返回该值,否则返回other13public T orElseGet(Supplier other)如果Optional值不为空,则返回该值,否则根据other另外生成一个14public T orElseThrow(Supplier exceptionSupplier)throws X如果Optional值不为空,则返回该值,否则通过supplier抛出一个异常 方法 1. isPresent:判断查询的类对象是否存在

被Optional使用的对象,不是null的话就返回true,是null的话则返回false

User user = null;
Optional optional = Optional.ofNullable(user);
if(  !  optional.isPresent()){
	throw  new RuntimeException("用户找不到!!!");
}

上面的结果其实就出现异常,因为user对象是null。所以optional.isPresent()结果就是false。所以出现异常

2. orElseThrow(): 相当于if ... throws

判断一个对象是否为null,如果为null,就会抛出异常

  public static User getUser(Integer userId){
        User user = null;
        user = Optional.ofNullable(user)
                .orElseThrow(()->new RuntimeException("用户找不到!!!"));//简化 简化 if + throws / if/else
        return user;
    }

应用场景:它可以简化if+throws场景 + springmvc统一异常处理

3. orElse():相当于 if + new (赋值默认值)

判断一个对象是否为null,如果为null,给你默认对象

public static User getUser(Integer userId)  {
    User user = null;
    user = Optional.ofNullable(user).orElse(new User());
    return user;
}

应用场景:if+throws场景 + springmvc统一异常处理

4. oElseGet():相当于 if + 加逻辑处理

相当于加了一个匿名内部类,里面可以写你想要进行的处理逻辑

user = Optional.ofNullable(user).orElseGet(()->{
    User user1 = new User();
    // 增加各种处理和逻辑
    return user1;
});

应用场景:例如数据查询是有值的,有些是没有值,但是我需要统计那些错误访问数据。

应用 :isPresent和orElse()

场景:当用户第一次注册给其设置默认昵称和密码:

User user = new User();
user.setNickname(Optional.ofNullable(user.getNickname()).orElse("学生"));
user.setPassword(Optional.ofNullable(user.getPassword()).orElse("123456"));
总结 of 和offNullAble区别
@Test
    public void m1(){
        Optional fullName2 = Optional.ofNullable(null);
        Optional fullName = Optional.of(null);
    }

  • 相同点
    • 两者都是去创建Optional对象
    • 两者都是给value成员变量赋值

问题: 为什么of方法会报空指针异常

去of源码查看其创建optional对象的代码:

 private Optional(T value) {
 	this.value = Objects.requireNonNull(value);
 }

点击requireNonNull查看:

public static  T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException(); // 如果value是null,就出现空指针异常
    return obj;
}

由此我们发现:of方法如果传入的对象为null,就直接返回NullPointerException
而ofNullAble源码则是当传值为空的时候,直接给创建一个空对象:

 public static  Optional ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
Optional中filter ,map,flatmap的认识 注意:filter ,map,flatmap都属于java.util.Stream的中间方法。但此处的filter方法与之前的stream流中间方法无关

它在Optional中的存在,其实还是去解决一个程序开发过程中集合为空问题。
作用:

集合中的元素如果不为空,就直接用filter/map/flatmap处理,
如果为空给要么抛出异常。要么默认初始化

实例:

List users = null;
        users = Optional.ofNullable(users) // 1: 创建一Optional并给Optional的value赋值null
                .filter((u) -> u.get(0).getId().equals(1))// 2: 调用的Optional中filter内部出现空异常,不报错,赋值空的Optional对象
                .orElse(new ArrayList<>()); // 3: 如果前面代码是空对象,则初始化集合
        System.out.println(users);

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5697246.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)