Java Optional

简介: 在日常开发中,NPE异常是导致应用程序失败的最常见原因。为了解决空指针异常,Google公司知名的 Guava项目引入了Optional类,它通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。

前言

image (1).png
在日常开发中,NPE异常是导致应用程序失败的最常见原因。为了解决空指针异常,Google公司知名的 Guava项目引入了Optional类,它通过使用检查空值的方式来防止代码污染,它可以使程序员书写更干净的代码。

Optional概述

Java的Optional类其实是"进口"的,它受Guava的Optional类的启发,在JDK8中引入,Optional实际上是个容器,它可以保存泛型值,或者仅仅保存一个null,它提供了很多方便处理的方法,同时也避免了我们在书写代码的时候,进行大量显式的空值检查了。

Method

ofNullable

Optional.of()、Optional.ofNullable()都是创建Optional对象的,他们的区别of()不允许参数是null,而ofNullable()则可以。

public static void main(String[] args) {
    User user1 =  new User("小明");
    User user2 =  null;
    Optional.of(user1);
    Optional.ofNullable(user2);
}

orElse

主要是用来处理当值为空时候的默认值,如果有值则返回该值,否则返回设置参数值

public static void main(String[] args) {
    User user1 =  new User("小明");
    User user2 =  null;
    User result = Optional.ofNullable(user2).orElse(user1);
    System.out.println(result);
}

map

值映射

public static void main(String[] args) {
    User user =  new User("小明", null);
    Integer age = Optional.ofNullable(user).map(User::getAge).orElse(-1);
}

filter

filter为过滤方法,如果filter方法中的表达式成立,方法会返回当前Optional对象值,否则返回一个值为空的 Optional对象。

public static void main(String[] args) {
    User user =  new User("小明", null);
    Integer age = Optional.ofNullable(user)
        .filter(u -> "小明".equals(u.getName()))
        .map(User::getAge)
        .orElse(-1);
}

isPresent

检查是否有值的另一个选择是ifPresent方法。该方法除了执行检查,还接受一个Consumer参数,如果对象不是空的,就对执行传入的表达式。

public static void main(String[] args) {
    User user =  new User("小明", null);
    Optional.ofNullable(user)
        .filter(u -> "小明".equals(u.getName()))
        .ifPresent(t-> System.out.println(t.getAge()));
}

orElseGet

这个方法会在有值的时候返回值,如果没有值,它会执行作为参数传入的Supplier表达式,并将返回其执行结果。

public static void main(String[] args) {
    User user1 =  null;
    User user2 =  new User("小明", null);
    User result = Optional.ofNullable(user1).orElseGet( () -> user2);
}

orElse和orElseGet区别

Optional对象为空而返回orElse或orElseGet中的默认值时,并无差异,都会执行其中的代码。但Optional对象不为空时,orElse还会执行其中的代码,而orElseGet不会执行。

orElseThrow

值不存在则抛出异常,存在则什么不做。

public static void main(String[] args) {
    User user1 =  null;
    User result = Optional.ofNullable(user1)
        .orElseThrow( () -> new ServiceException());
}

Example

/**
 * 防止从user中取出的数据为空,用Optional赋默认值0
 */
public static void main(String[] args) {
    User user =  new User("小明", null);
    Integer age = null;
    user.setAge(
        Optional.ofNullable(age).orElse(0)
    );
}
/**
* 非空则取其name,否则赋空
*/
public static void main(String[] args) {
    User user1 =  new User("小明", null);
    User user2 =  new User(null, 20);
    user2.setName(
        Optional.ofNullable(user1).map(User::getName).orElse("")
    );
}
/**
 * 多map转换
 */
public static void main(String[] args) {
    Object strObj = String.valueOf("aAvwR");
    Optional.ofNullable(str)
        .map(Object::toString)
        .map(String::toLowerCase)
        .orElse("");
}
/**
 * 根据姓名集合查用户集,如果结果不为空的话,取出地址构成List,否则新建List
 */
List<User> users = userDao.queryUserByNames(request.getNames());

List<String> orderNoList = Optional.ofNullable(users)
    .map(u -> u.stream().map(User::getAddress)
    .collect(Collectors.toList()))
    .orElse(Lists.newArrayList());
/**
 * 先取request实体中的AccountId,没有的话从user中取
 */
Long accountId = Optional.ofNullable(request.getAccountId())
    .orElse(Optional.ofNullable(user)
            .map(User::getAccountId).orElse(null));
/**
* 分页默认值
*/
paging.setOffset(
    (long)Optional.ofNullable(param.getOffset()).orElse(DEFAULT_PAGE_OFFSET)
);
paging.setCount(
    Optional.ofNullable(param.getCount()).orElse(DERAULT_PAGE_COUNT)
);
/**
* 替代IF输出
*/
public static void main(String[] args) {
    final User user = new User("小明");

    Optional.ofNullable(user.getName())
        .filter(StringUtils::isNotBlank)
        .ifPresent(System.out::println);
}
目录
相关文章
|
7月前
|
Java Unix 程序员
java 8 新特性讲解Optional类--Fork/Join 框架--新时间日期API--以及接口的新特性和注解
java 8 新特性讲解Optional类--Fork/Join 框架--新时间日期API--以及接口的新特性和注解
98 1
|
4月前
|
安全 Java API
告别繁琐编码,拥抱Java 8新特性:Stream API与Optional类助你高效编程,成就卓越开发者!
【8月更文挑战第29天】Java 8为开发者引入了多项新特性,其中Stream API和Optional类尤其值得关注。Stream API对集合操作进行了高级抽象,支持声明式的数据处理,避免了显式循环代码的编写;而Optional类则作为非空值的容器,有效减少了空指针异常的风险。通过几个实战示例,我们展示了如何利用Stream API进行过滤与转换操作,以及如何借助Optional类安全地处理可能为null的数据,从而使代码更加简洁和健壮。
123 0
|
3月前
|
设计模式 Java
结合HashMap与Java 8的Function和Optional消除ifelse判断
`shigen`是一位致力于记录成长、分享认知和留住感动的博客作者。本文通过具体代码示例探讨了如何优化业务代码中的if-else结构。首先展示了一个典型的if-else处理方法,并指出其弊端;然后引入了策略模式和工厂方法等优化方案,最终利用Java 8的Function和Optional特性简化代码。此外,还提到了其他几种消除if-else的方法,如switch-case、枚举行、SpringBoot的IOC等。一起跟随shigen的脚步,让每一天都有所不同!
39 10
结合HashMap与Java 8的Function和Optional消除ifelse判断
|
7月前
|
自然语言处理 Java API
Java 8的Stream API和Optional类:概念与实战应用
【5月更文挑战第17天】Java 8引入了许多重要的新特性,其中Stream API和Optional类是最引人注目的两个。这些特性不仅简化了集合操作,还提供了更好的方式来处理可能为空的情况,从而提高了代码的健壮性和可读性。
177 7
|
4月前
|
安全 Java API
Java 8 流库的魔法革命:Filter、Map、FlatMap 和 Optional 如何颠覆编程世界!
【8月更文挑战第29天】Java 8 的 Stream API 通过 Filter、Map、FlatMap 和 Optional 等操作,提供了高效、简洁的数据集合处理方式。Filter 用于筛选符合条件的元素;Map 对元素进行转换;FlatMap 将多个流扁平化合并;Optional 安全处理空值。这些操作结合使用,能够显著提升代码的可读性和简洁性,使数据处理更为高效和便捷。
148 0
|
6月前
|
Java API 容器
Java 8 的流库:Filter、Map、FlatMap 及 Optional 的概念与用法
【6月更文挑战第9天】Java 8 引入了许多强大的新特性,其中流库(Stream API)和 Optional 类极大地简化了集合操作和空值处理。本文将深入探讨 filter、map、flatMap 以及 Optional 的概念和用法,并提供示例代码来展示其实际应用。
86 4
|
5月前
|
安全 Java 数据处理
Java面试题:什么是Java中的Optional类及其使用场景?
Java面试题:什么是Java中的Optional类及其使用场景?
68 0
|
5月前
|
Java 容器
Java中使用Optional类的建议
Java中使用Optional类的建议
|
6月前
|
安全 NoSQL Java
探索Java Optional类:构造器、成员变量与方法
探索Java Optional类:构造器、成员变量与方法
|
7月前
|
安全 Java 开发者
Java一分钟之-Optional类:优雅处理null值
【5月更文挑战第13天】Java 8的`Optional`类旨在减少`NullPointerException`,提供优雅的空值处理。本文介绍`Optional`的基本用法、创建、常见操作,以及如何避免错误,如直接调用`get()`、误用`if (optional != null)`检查和过度使用`Optional`。正确使用`Optional`能提高代码可读性和健壮性,建议结合实际场景灵活应用。
292 3