java中optional的一些常用方法总结

 更新时间:2023年04月01日 11:23:00   作者:xy724518356  
Java8引入了一个非常强大的特性就是Optional类,其主要解决的问题就是我们编程时常常遇到的空指针异常,下面这篇文章主要给大家介绍了关于java中optional的一些常用方法,需要的朋友可以参考下

前言

Java中的Optional是一个容器对象,它可以包含一个非空值,也可以为空。它的主要作用是在编写代码时避免空指针异常。

java 8 中Optional的完整用法如下:

1. 创建Optional对象

可以通过of()方法创建一个包含非空值的Optional对象,例如:

Optional<String> optional = Optional.of("value");

也可以通过ofNullable()方法创建一个包含可能为空的值的Optional对象,例如:

Optional<String> optional = Optional.ofNullable(null);

2. 获取Optional对象的值

可以通过get()方法获取Optional对象中的非空值,例如:

String value = optional.get();

如果Optional对象中的值为空,调用get()方法会抛出NoSuchElementException异常。因此,在调用get()方法之前,最好先使用isPresent()方法判断Optional对象是否包含一个非空值。

3. 判断Optional对象是否包含非空值

可以使用isPresent()方法判断Optional对象是否包含一个非空值,例如:

if (optional.isPresent()) {
    // Optional对象包含非空值
} else {
    // Optional对象为空
}

也可以使用ifPresent()方法在Optional对象包含非空值时执行一些操作,例如:

optional.ifPresent(value -> System.out.println(value));

4. 获取Optional对象中的值或默认值

可以使用orElse()方法获取Optional对象中的值或默认值,例如:

String value = optional.orElse("default");

如果Optional对象中的值为空,则返回指定的默认值。

5. 获取Optional对象中的值或抛出异常

可以使用orElseThrow()方法获取Optional对象中的值或抛出异常,例如:

String value = optional.orElseThrow(() -> new RuntimeException("value is null"));

如果Optional对象中的值为空,则抛出指定的异常。

6. 转换Optional对象中的值

可以使用map()方法将Optional对象中的值转换为另一个类型的值,例如:

Optional<Integer> optional = Optional.of("123").map(Integer::parseInt);

如果Optional对象中的值为空,则返回一个空的Optional对象。

7. 过滤Optional对象中的值

可以使用filter()方法过滤Optional对象中的值,例如:

Optional<String> optional = Optional.of("value").filter(value -> value.startsWith("v"));

如果Optional对象中的值不满足指定的过滤条件,则返回一个空的Optional对象。

Java 9 增强

我们介绍了 Java 8 的特性,Java 9 为 Optional 类添加了三个方法:or()、ifPresentOrElse() 和 stream()。

or() 方法与 orElse() 和 orElseGet() 类似,它们都在对象为空的时候提供了替代情况。or() 的返回值是由 Supplier 参数产生的另一个 Optional 对象。

如果对象包含值,则 Lambda 表达式不会执行:

@Test
public void whenEmptyOptional_thenGetValueFromOr() {
    User result = Optional.ofNullable(user)
      .or( () -> Optional.of(new User("default","1234"))).get();

    assertEquals(result.getEmail(), "default");
}

上面的示例中,如果 user 变量是 null,它会返回一个 Optional,它所包含的 User 对象,其电子邮件为 “default”。

ifPresentOrElse() 方法需要两个参数:一个 Consumer 和一个 Runnable。如果对象包含值,会执行 Consumer 的动作,否则运行 Runnable。

如果你想在有值的时候执行某个动作,或者只是跟踪是否定义了某个值,那么这个方法非常有用:

Optional.ofNullable(user).ifPresentOrElse( u -> logger.info("User is:" + u.getEmail()),
  () -> logger.info("User not found"));

补充:Optional争议点

其实到底该不该用Optional,业界还是有不少争议的,一方面是Optional能强迫开发者处理null值,但另一方面是Optional又非常容易滥用,特别是一些开发者拿到Optional之后就直接调用get()或ifPresent()方法,这样几乎没解决任何问题,还加重了编码负担。

因此,我的建议是,在你不知道该不该使用Optional的场景,那就先别用。

下面是一些使用Optional的场景参考,如下:

  1. Optional一般用于返回值
    Optional大多用于返回值,不推荐用在成员变量或方法参数中。
  2. Optional本身不判null
    永远都不要给Optional赋值null,也不要判断Optional本身是否为null,这是因为Optional本来就是解决null的,再引入null就没意思了,这应该成为业界共识。
  3. 集合不使用Optional
    因为集合有Collections.emptyList()等更好的处理方法了,没必要再使用Optional。
  4. 函数式处理值
    从上面的用法介绍中就能发现,Optional提供了很多lambda函数式处理的方法,如filter、map等,这些是使用Optional时比较推荐使用的,因为Optional能帮你自动处理null值情况,避免NPE异常。
  5. 多层属性获取
    前面举过这个代码样例,我觉得这是Optional使用收益最明显的一个场景。
  6. 不返回null胜过返回Optional
    返回Optional给调用方,会强制调用方处理null情况,会给调用方增加一些的编码负担,特别是复用度很高的函数。
    但如果调用方大多数情况下都不期望获取到null,那应该实现一个这样的方法,要么返回值,要么异常,如下:
/**
 * 查询订单,要么返回订单,要么异常
 */
public Order getOrderByIdOrExcept(Long orderId){
    Order order = orderMapper.getOrderById(orderId);
    if(order == null){
        throw new BizException("根据单号" + orderId + "未查询到订单!");
    }
    return order;
}
 
/**
 * 查询订单,值可能为null
 */
public Optional<Order> getOrderById(Long orderId){
    Order order = orderMapper.getOrderById(orderId);
    return Optional.ofNullable(order);
}

由于后面处理代码依赖订单数据,获取不到订单数据,代码也没法往下走,所以在大多数情况下,选择使用getOrderByIdOrExcept方法更好,即避免了NPE,又避免了增加编码负担!

总结

到此这篇关于java中optional的一些常用方法总结的文章就介绍到这了,更多相关java optional常用方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • spring的xml文件打开没有namespace等操作选项的解决方案

    spring的xml文件打开没有namespace等操作选项的解决方案

    这篇文章主要介绍了spring的xml文件打开没有namespace等操作选项的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java高并发之CyclicBarrier的用法详解

    Java高并发之CyclicBarrier的用法详解

    CyclicBarrier 是 Java 中的一种同步工具,它可以让多个线程在一个屏障点处等待,直到所有线程都到达该点后,才能继续执行。本文就来和大家聊聊它的用法,需要的可以参考一下
    2023-03-03
  • Java生产1-100的随机数简单实例(分享)

    Java生产1-100的随机数简单实例(分享)

    下面小编就为大家带来一篇Java生产1-100的随机数简单实例(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • MyBatis-plus使用lambda条件构造器报错问题及解决

    MyBatis-plus使用lambda条件构造器报错问题及解决

    这篇文章主要介绍了MyBatis-plus使用lambda条件构造器报错问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • SpringSecurity6自定义JSON登录的实现

    SpringSecurity6自定义JSON登录的实现

    目前最新版的Spring Boot已经到了3.0.5了,随之而来Spring Security 目前的版本也到了6.0.2了,Spring Security写法的变化特别多,本文就来介绍下,感兴趣的可以了解一下
    2023-12-12
  • springboot中Getmapping获取参数的实现方式

    springboot中Getmapping获取参数的实现方式

    这篇文章主要介绍了springboot中Getmapping获取参数的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Java 3D入门之基本图形功能 附源码

    Java 3D入门之基本图形功能 附源码

    Java3D API是Sun定义的用于实现3D显示的接口。3D技术是底层的显示技术,Java3D提供了基于Java的上层接口。Java3D把OpenGL和DirectX这些底层技术包装在Java接口中。这种全新的设计使3D技术变得不再繁琐且可以加入到J2SE、J2EE的整套架构,故保证了Java3D技术强大的扩展性
    2021-10-10
  • Java修改eclipse中web项目的server部署路径问题

    Java修改eclipse中web项目的server部署路径问题

    这篇文章主要介绍了Java修改eclipse中web项目的server部署路径,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • Java 8 中的 10 个特性总结及详解

    Java 8 中的 10 个特性总结及详解

    本主要介绍Java 8中的新特性,这里整理了相关资料并整理了10个特性,逐一介绍说明,有兴趣的朋友可以参考下
    2016-09-09
  • 如何将字符串、字节数组转为输入流

    如何将字符串、字节数组转为输入流

    这篇文章主要介绍了如何将字符串、字节数组转为输入流问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05

最新评论