栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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()无参构造,构造一个空Optional
2private Optional(T value)根据传入的非空value构建Optional
3public 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,否则返回一个空的Optional
10public Optional map(Function mapper)如果Optional设置了value,则调用Function对值进行处理,并返回包含处理后值的Optional,否则返回空Optional
11public Optional flatMap(Function> mapper)与map()方法类型,不同的是它的mapper结果已经是一个Optional,不需要再对结果进行包装
12public T orElse(T other)如果Optional值不为空,则返回该值,否则返回other
13public 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);
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号