Java 8新特性之Optional

简介: 在进行日常Java开发中遇见NullPointerException已经算是家常便饭了,有些情况没有考虑到有可能出现空指针异常,尤其是新手,即使考虑到了也要使用if-else去判断是否为空,这样有时候会让代码看上去复杂一些.现在Java8有了Optional之后,空指针的校验就变得非常的方便和简洁,下面我们就来看看Optional的用法.

前言

在进行日常Java开发中遇见NullPointerException已经算是家常便饭了,有些情况没有考虑到有可能出现空指针异常,尤其是新手,即使考虑到了也要使用if-else去判断是否为空,这样有时候会让代码看上去复杂一些.
现在Java8有了Optional之后,空指针的校验就变得非常的方便和简洁,下面我们就来看看Optional的用法.

一、Optional 类

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 类的引入很好的解决空指针异常。

二、常用方法

// 判断Optional中的值是否不为空,不为空返回true,反之返回false
public boolean isPresent()

// 获取Optional中的值,如果值为空则抛出NoSuchElementException
public T get()

// 创建一个Optional<T>对象,如果传入的value为空则抛出NullPointerException
public static <T> Optional<T> of(T value)
 
// 创建一个Optional<T>对象,如果传入的value为空则返回一个空的Optional对象(new Optional<>())
public static <T>  Optional<T> ofNullable(T value)
 
// 判断Optional中的值是否为空,不为空则返回值,为空则返回传入的值other
public T orElse(T other)
 
// 判断Optional中的值是否为空,不为空则返回值,为空则抛出传入的异常
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
 
//如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果
public T orElseGet(Supplier<? extends T> other)

// 如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional
public<U> Optional<U> map(Function<? super T, ? extends U> mapper)  

三、常用方法应用

首先我们需要创建一个实体类,比如User.java

@Entity
@Table(name="user")
@Data
public class User{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String userName;

    private String password;

    private Integer sex;
    @Column(name="last_login_time")
    private Date lastLoginTime;
    
    @Override
    public String toString() {
        return "admin{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", sex=" + sex +
                ", lastLoginTime=" + lastLoginTime +
                '}';
    }
}

通常情况下我们写的判断传入参数是否为空的方法是这样子,比如我们要返回此用户的name。如果按传统的写法就会非常的冗余,阅读性较差。

public String GetNameTest(User user){
        if(user==null){
                return "This user does not exist ";
        }else{
            if (user.getUserName() == null || user.getName().isEmpty())
                    return "This username is null ";
                else
                    return user.getUserName();
        }

    }

使用Optional之后一切就变得很方便简洁了,可读性也提高了。

Optional.ofNullable(user)
        .map(temp -> temp.getUserName())
        /*.map(new Function<User,String>(){// temp -> temp.getUserName()
                         @Override
                         public String apply(admin s) {
                             return s.getUserName();
                         })*/
        .orElseThrow(() -> new NullPointerException("user or userName is null"));
        /*.orElseThrow(new Supplier<NullPointerException>() {
                    @Override
                    public NullPointerException get() {
                        return new NullPointerException("user or userName is null");
                    }
                })*/

此处补充一些Java 8另一个新特性Lambda 表达式,也可称为闭包。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
语法规则为:
**(parameters) -> expression

(parameters) ->{ statements; }**
简单举例:

// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
  

看到这里相信大家对上一代码片段有一定层度的理解了,这里为了方便大家一起学习,小编将lambda学习教程之一的链接提供给大家。

下面我们看一下这三个函数的源码并进行分析

private final T value;
 
private static final Optional<?> EMPTY = new Optional<>();
 
public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
}
 
public static<T> Optional<T> empty() {
    Optional<T> t = (Optional<T>) EMPTY;
    return t;
}
 
public static <T> Optional<T> of(T value) {
    return new Optional<>(value);
}
 
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value));
    }
}
 
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
    if (value != null) {
        return value;
    } else {
        throw exceptionSupplier.get();
    }
}

ofNullable():调用ofNullable()的时候会对传入的value值进行空验证,如果不为空则调用of()方法使用value值创建一个Optional对象,如果为空则new一个空的Optional;

map():调用map()方法的时候也会对value进行空验证,如果不为空则进行后面的操作,如果为空则同样new一个空的Optional;

orElseThrow():调用orElseThrow()方法的时候也会对value进行空验证,如果不为空则返回对应的值,如果为空则抛出一个传入的异常。

目录
相关文章
|
1天前
|
安全 前端开发 Java
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择。依赖注入使对象管理交由Spring容器处理,实现低耦合高内聚;AOP则分离横切关注点如事务管理,增强代码模块化。Spring还提供MVC、Data、Security等模块满足多样需求,并通过Spring Boot简化配置与部署,加速微服务架构构建。掌握这些核心概念与工具,开发者能更从容应对挑战,打造卓越应用。
7 1
|
1天前
|
分布式计算 Java API
Java 8带来了流处理与函数式编程等新特性,极大提升了开发效率
Java 8带来了流处理与函数式编程等新特性,极大提升了开发效率。流处理采用声明式编程模型,通过filter、map等操作简化数据集处理,提高代码可读性。Lambda表达式支持轻量级函数定义,配合Predicate、Function等接口,使函数式编程无缝融入Java。此外,Optional类及新日期时间API等增强功能,让开发者能更优雅地处理潜在错误,编写出更健壮的应用程序。
7 1
|
5天前
|
Java API Apache
JDK8到JDK24版本升级的新特性问题之在Java中,HttpURLConnection有什么局限性,如何解决
JDK8到JDK24版本升级的新特性问题之在Java中,HttpURLConnection有什么局限性,如何解决
|
4天前
|
自然语言处理 Java 应用服务中间件
Java 18 新特性解析
Java 18 新特性解析
|
5天前
|
Oracle 安全 Java
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
|
5天前
|
Java API 开发者
JDK8到JDK17版本升级的新特性问题之SpringBoot选择JDK17作为最小支持的Java lts版本意味着什么
JDK8到JDK17版本升级的新特性问题之SpringBoot选择JDK17作为最小支持的Java lts版本意味着什么
JDK8到JDK17版本升级的新特性问题之SpringBoot选择JDK17作为最小支持的Java lts版本意味着什么
|
6天前
|
算法 关系型数据库 MySQL
一天五道Java面试题----第七天(mysql索引结构,各自的优劣--------->事务的基本特性和隔离级别)
这篇文章是关于MySQL的面试题总结,包括索引结构的优劣、索引设计原则、MySQL锁的类型、执行计划的解读以及事务的基本特性和隔离级别。
|
17天前
|
Java API 数据处理
Java 8新特性:Stream API的实用指南
【8月更文挑战第3天】在Java 8中,最引人注目的新特性之一是Stream API。这个API允许开发者以声明式方式处理数据集合,提供了一种高效且易于理解的数据处理方法。本文将介绍Stream API的基本概念、常用操作以及如何在实际开发中应用。
|
5天前
|
Java 编译器 开发者
JDK8到JDK23版本升级的新特性问题之编写一个简单的module-info.java文件,如何实现
JDK8到JDK23版本升级的新特性问题之编写一个简单的module-info.java文件,如何实现
|
5天前
|
算法 关系型数据库 MySQL
一天五道Java面试题----第七天(mysql索引结构,各自的优劣--------->事务的基本特性和隔离级别)
这篇文章是关于MySQL的面试题总结,包括索引结构的优劣、索引设计原则、MySQL锁的类型、执行计划的解读以及事务的基本特性和隔离级别。