Java8 Optional使用详解

文章目录

  • [Optional 简介](#Optional 简介)
  • [1 使用Optional创建返回值](#1 使用Optional创建返回值)
    • [1.1 使用of创建非空对象](#1.1 使用of创建非空对象)
    • [1.2 使用ofNullable创建可以为空的对象](#1.2 使用ofNullable创建可以为空的对象)
  • [2 对Optional的处理](#2 对Optional的处理)
    • [2.1 使用 非空表达式 处理对象 ifPresent](#2.1 使用 非空表达式 处理对象 ifPresent)
    • [2.2 设置默认值(空值下的处理)](#2.2 设置默认值(空值下的处理))
    • [2.3 过滤值](#2.3 过滤值)
    • [2.4 转换值](#2.4 转换值)
  • [3 综合应用](#3 综合应用)
  • 参考:

Optional 简介

使用Optional用来表示一个引用对象存在或者不存在

Optional类主要用来处理返回值为null的情况,避免出现对返回对象操作发生NullPointerException的情况,使得代码更加健壮

Optional是容器对象,可能包含或者不包含非NULL值

常用API

  • ofNullable创建Optional对象
  • ifPresent对非null对象继续处理
  • orElseGet对null设置默认值
  • filter过滤结果
  • map映射新的Optional对象

正确使用Optional

  • 避免使用Optional.isPresent来检查实例是否存在,然后再操作,这样与if (obj != null)的使用方式没有区别,可以使用Optional.ifPresent(u -> System.out.println(u.getName())))
  • 避免使用Optional.get来获取对象,可能会出现NPE(NullPointerException)的问题,使用设置默认值的方式获取Optional对象,userOpt.orElseGet(() -> new User(-1, "Empty"))
  • 避免使用Optional作为类或者实例属性
  • 避免使用Optional作为方法的参数

1 使用Optional创建返回值

1.1 使用of创建非空对象

java 复制代码
public String findUserById(int id) {  
    if (id == 1) {  
        return "Alice";  
    } else {  
        return null;  
    }
}

使用Option处理

java 复制代码
import java.util.Optional;  
  
public Optional<String> findUserById(int id) {  
    if (id == 1) {  
        return Optional.of("Alice");  
    } else {  
        return Optional.empty();  
    }  
}

传入Optional.of的方法的参数必须时非空的,否则抛出NPE,使用ofNullable来创建非空值

1.2 使用ofNullable创建可以为空的对象

java 复制代码
User user = null;
Optional<User> userOpt = Optional.ofNullable(user);

2 对Optional的处理

2.1 使用 非空表达式 处理对象 ifPresent

如果对象存在,则对其进行处理,否则不处理

java 复制代码
userOpt.ifPresent(u -> System.out.println(u.getName()));

2.2 设置默认值(空值下的处理)

创建Optional对象的时候,设置默认值

1 基本用法

如果对象不为null,则返回该对象;

java 复制代码
User user = null;
User myUser = Optional.ofNullable(user).orElse(new User(-1, "Empty"))
2 表达式处理的区别

orElse的参数类型不同,如果对象为null,则执行表达式

java 复制代码
User user = null;
User myUser = Optional.ofNullable(user).orElseGet(() -> new User(-1, "Empty"))
两种设置默认值方法的不同

当Optional中的对象为null的时候,orElseGet方法并不会执行

java 复制代码
public static void getValue() { System.out.println("getValue!"); }

User user = null;
System.out.println("orElse")
User testUser1 = Optional.ofNullable(user).orElse(getValue());
System.our.println("orElseGet")
User testUser2 = Optional.ofNullable(user).orElseGet(Main::getValue)

注意: 类名::方法名是Java8新语法,表明该方法不一定会被调用

输出

shell 复制代码
orElse
getValue!
orElseGet

使用orElseGet的性能会更佳!

2.3 过滤值

对Optional中的对象进行按照条件进行筛选

需求:筛选id大于10的user

java 复制代码
User user = new User(100, "zhangsan");
Optional<User> userOpt = Optional.ofNullable(user);
userOpt.filter(u -> u.id > 10).ifPresent(System.out.println(u.getName));

存在多个条件:id大于10并小于100

java 复制代码
Predicate<User> userIdGt10 = u -> u.id > 10;
Predicate<User> userIdLt100 = u -> u.id < 100;

User use = new User(30, "lisi");
Optional<User> userOpt = Optional.ofNullable(user);
userOpt.filter(u -> userIdGt10.and(userIdLt100)).ifPresent(System.out.println(u.getName()));

使用optional进行条件过滤,使用一行代码就可以解决;如果使用if-else代码比较冗长

2.4 转换值

将一个Optional对象转换为另一个Optional对象

需求:取出user中的Name

java 复制代码
User user = new User(10, "zhangsan");
Optional<User> userOpt = Optional.ofNullable(user);
Optional<String> name = userOpt.map(User::getName);
name.orElseGet(() -> "empty").ifPresent(str -> System.out.println(str));

3 综合应用

对user对象设置默认值,并筛选其中长度大于10小于100的user的小写名字

java 复制代码
Predicate<String> lenGt10 = name -> name.length() > 10;
Predicate<String> lenLt100 = name -> name.length() < 100;

User user = new User(10, "zhangsan");
Optional<User> userOpt = Optional.ofNullable(user);
userOpt.orElseGet(() -> new User(-1, "")).map(User::getName).map(String::toLowerCase).fileter(lenGt10.and(lenLt100)).ifPresent(name -> System.out.println(name));

参考:

Java8 Optional最佳指南,优雅解决空指针 https://javabetter.cn/java8/optional.html

Java8 Optional使用总结 https://www.cnblogs.com/kingsonfu/p/11009574.html

相关推荐
李慕婉学姐16 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆18 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin18 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model200518 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉18 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国18 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_9418824819 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈19 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_9919 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹19 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理