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进行空验证,如果不为空则返回对应的值,如果为空则抛出一个传入的异常。

目录
相关文章
|
2月前
|
存储 安全 Java
Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
【10月更文挑战第17天】Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
78 2
|
2月前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
46 3
|
2月前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
36 2
|
10天前
|
存储 Java 开发者
什么是java的Compact Strings特性,什么情况下使用
Java 9引入了紧凑字符串特性,优化了字符串的内存使用。它通过将字符串从UTF-16字符数组改为字节数组存储,根据内容选择更节省内存的编码方式,通常能节省10%至15%的内存。
|
19天前
|
存储 Java 数据挖掘
Java 8 新特性之 Stream API:函数式编程风格的数据处理范式
Java 8 引入的 Stream API 提供了一种新的数据处理方式,支持函数式编程风格,能够高效、简洁地处理集合数据,实现过滤、映射、聚合等操作。
35 6
|
1月前
|
分布式计算 Java API
Java 8引入了流处理和函数式编程两大新特性
Java 8引入了流处理和函数式编程两大新特性。流处理提供了一种声明式的数据处理方式,使代码更简洁易读;函数式编程通过Lambda表达式和函数式接口,简化了代码书写,提高了灵活性。此外,Java 8还引入了Optional类、新的日期时间API等,进一步增强了编程能力。这些新特性使开发者能够编写更高效、更清晰的代码。
33 4
|
2月前
|
存储 Java API
优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。
【10月更文挑战第19天】本文介绍了如何优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。内容包括Map的初始化、使用Stream API处理Map、利用merge方法、使用ComputeIfAbsent和ComputeIfPresent,以及Map的默认方法。这些技巧不仅提高了代码的可读性和维护性,还提升了开发效率。
95 3
|
2月前
|
存储 安全 Java
Java Map新玩法:深入探讨HashMap和TreeMap的高级特性
【10月更文挑战第19天】Java Map新玩法:深入探讨HashMap和TreeMap的高级特性,包括初始容量与加载因子的优化、高效的遍历方法、线程安全性处理以及TreeMap的自然排序、自定义排序、范围查询等功能,助你提升代码性能与灵活性。
29 2
|
2月前
|
Java 开发者
在Java集合世界中,Set以其独特的特性脱颖而出,专门应对重复元素
在Java集合世界中,Set以其独特的特性脱颖而出,专门应对重复元素。通过哈希表和红黑树两种模式,Set能够高效地识别并拒绝重复元素的入侵,确保集合的纯净。无论是HashSet还是TreeSet,都能在不同的场景下发挥出色的表现,成为开发者手中的利器。
28 2
|
2月前
|
Java
Java Set以其“不重复”的特性,为我们提供了一个高效、简洁的处理唯一性约束数据的方式。
【10月更文挑战第16天】在Java编程中,Set接口确保集合中没有重复元素,每个元素都是独一无二的。HashSet基于哈希表实现,提供高效的添加、删除和查找操作;TreeSet则基于红黑树实现,不仅去重还能自动排序。通过这两个实现类,我们可以轻松处理需要唯一性约束的数据,提升代码质量和效率。
40 2
下一篇
DataWorks