Java 8新特性之 Optional 类
前言
java.util.Optional 是java8中引进的一个新的类,我们通过Optional类的源码可以看到,该方法的作用可以对可能缺失的值进行建模,而不是直接将null赋值给变量。
Optional类产生背景
作为java开发者,业务逻辑中需要经常检查对象是否为空,因此业务中会产生大量的if else 结构和判断对象是否为空的方法(已经有很多判断对象是否为空的方法 例如: StringUtils,Objects,CollectionUtils等工具类)。为了代码的可读性和可维护性,Optional类应运而生。
Optional类API
1: static Optional empty() 返回空的 Optional 实例。
/**
* Returns an empty {@code Optional} instance. No value is present for this
* Optional.
* @return an empty {@code Optional}
*/
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
2: Optional filter(Predicate<? super predicate) 如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional
/**
* If a value is present, and the value matches the given predicate,
* return an {@code Optional} describing the value, otherwise return an
* empty {@code Optional}.
*/
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
3: Optional flatMap(Function<? super T,Optional> mapper) 如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional
/**
* If a value is present, apply the provided {@code Optional}-bearing
* mapping function to it, return that result, otherwise return an empty
*/
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNonNull(mapper.apply(value));
}
}
4:T get() 如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException
/**
* If a value is present in this {@code Optional}, returns the value,
* otherwise throws {@code NoSuchElementException}.
*/
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
5: void ifPresent(Consumer<? super T> consumer) 如果值存在则使用该值调用 consumer , 否则不做任何事情。
/**
* If a value is present, invoke the specified consumer with the value,
* otherwise do nothing.
*
* @throws NullPointerException if value is present and {@code consumer} is
* null
*/
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
6: boolean isPresent() 如果值存在则方法会返回true,否则返回 false
/**
* Return {@code true} if there is a value present, otherwise {@code false}.
*
* @return {@code true} if there is a value present, otherwise {@code false}
*/
public boolean isPresent() {
return value != null;
}
7: Optional map(Function<? super T,? extends U> mapper) 如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional
/**
* If a value is present, apply the provided mapping function to it,
* and if the result is non-null, return an {@code Optional} describing the
* result. Otherwise return an empty {@code Optional}.
*
* @apiNote This method supports post-processing on optional values, without
* the need to explicitly check for a return status. For example, the
* following code traverses a stream of file names, selects one that has
* not yet been processed, and then opens that file, returning an
* {@code Optional<FileInputStream>}:
*
* <pre>{@code
* Optional<FileInputStream> fis =
* names.stream().filter(name -> !isProcessedYet(name))
* .findFirst()
* .map(name -> new FileInputStream(name));
* }</pre>
*
* Here, {@code findFirst} returns an {@code Optional<String>}, and then
* {@code map} returns an {@code Optional<FileInputStream>} for the desired
* file if one exists.
*/
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));
}
}
8: static Optional of(T value) 返回一个指定非null值的Optional。
/**
* Returns an {@code Optional} with the specified present non-null value.
*/
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
9: static Optional ofNullable(T value) 如果为非空,返回 Optional 描述的指定值,否则返回空的 Optional
/**
* Returns an {@code Optional} describing the specified value, if non-null,
* otherwise returns an empty {@code Optional}.
*/
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
10: T orElse(T other) 如果存在该值,返回值, 否则返回 other
/**
* Return the value if present, otherwise return {@code other}.
*
* @param other the value to be returned if there is no value present, may
* be null
* @return the value, if present, otherwise {@code other}
*/
public T orElse(T other) {
return value != null ? value : other;
}
11: T orElseGet(Supplier<? extends T> other) 如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。
/**
* Return the value if present, otherwise invoke {@code other} and return
* the result of that invocation.
*/
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
12: T orElseThrow(Supplier<? extends X> exceptionSupplier)
如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常
/**
* Return the contained value, if present, otherwise throw an exception
* to be created by the provided supplier.
*
* @apiNote A method reference to the exception constructor with an empty
* argument list can be used as the supplier. For example,
* {@code IllegalStateException::new}
*/
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
Optional类使用
1: 判断方法返回值
public class OptionalTest {
public static void main(String[] args) {
Optional<User> user = Optional.of(getUser());
if (user.isPresent()) {
//执行其他代码
}
}
public static User getUser() {
return new User();
}
}
2: 判断方法参数值
public static List<User> getUsers(Params params) {
//判断参数params是否为空,并取OrganizationId的值
String organizationId = Optional.ofNullable(params).map(Params::getOrganizationId).orElse(null);
List<User> users = new ArrayList<>();
users.add(new User());
return users;
}
除了上面常用的方法 还有一些API根据自己的需求进行组装,满足自己的业务逻辑。
Optional工具类
// 判断List是否为空
public <T> Stream<T> ofNullable(Iterable<T> target) {
if (target != null) {
return Lists.newArrayList(target).stream();
} else {
return empty();
}
}
//过滤List中null的元素
public <T> List<T> filterNullElem(Iterable<T> target) {
return ofNullable(target).filter(Objects::nonNull).collect(Collectors.toList());
}
总结
上面介绍了Optional类的API方法和常见用法。这些方法是最原始的方法,可以根据自己的业务开发场景,封装适合自己的工具类,方便快速开发。文章中如有错误之处 请不吝赐教,谢谢读者阅读。
Java 8新特性之 Optional 类的更多相关文章
- JAVA 8 新特性 __ Optional 类
Optional 类是一个可以作为null容器的对象,若值存在调用isPresent()就返回 true,调用get()会返回该对象. Optional是一个容器,可以保存类型T的值,或者仅仅保存nu ...
- Java 15 新特性:隐藏类
什么是隐藏类 隐藏类,是一种不能被其他类直接使用的类.引入隐藏类的主要目的是给框架来使用,使得框架可以在运行时生成类,并通过反射间接使用它们.可能有点抽象,不要紧,下面我们通过一个例子来直观的认识它! ...
- 【Java8新特性】Optional类在处理空值判断场景的应用 回避空指针异常 编写健壮的应用程序
一.序言 空值异常是应用运行时常见的异常,传统方式为了编写健壮的应用,常常使用多层嵌套逻辑判断回避空指针异常.Java8新特性之Optional为此类问题提供了优雅的解决方式. 广大程序员朋友对空值异 ...
- Java 16 新特性:record类
以前我们定义类都是用class关键词,但从Java 16开始,我们将多一个关键词record,它也可以用来定义类.record关键词的引入,主要是为了提供一种更为简洁.紧凑的final类的定义方式. ...
- java8新特性之Optional类
NullPointException可以说是所有java程序员都遇到过的一个异常,虽然java从设计之初就力图让程序员脱离指针的苦海,但是指针确实是实际存在的,而java设计者也只能是让指针在java ...
- 010-jdk1.8版本新特性二-Optional类,Stream流
1.5.Optional类 1.定义 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个 ...
- Java 8新特性之 Optional(八恶人-5)
Oswaldo Mobray 莫博瑞·奥斯瓦尔多 “I‘m Oswaldo Mobray, the hangman in these parts.” “我是莫博瑞·奥斯瓦尔多,这片地区的绞刑官.” 一 ...
- java8新特性六-Optional 类
Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个容器:它可以保存类型T的值,或者仅仅保 ...
- 【Java8新特性】Optional 类
概述 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个容器:它可以保存类型T的值,或者 ...
- Java 12 新特性介绍,快来补一补
Java 12 早在 2019 年 3 月 19 日发布,它不是一个长久支持(LTS)版本.在这之前我们已经介绍过其他版本的新特性,如果需要可以点击下面的链接进行阅读. Java 11 新特性介绍 J ...
随机推荐
- 问题记录[ PPOME 修改子屏幕日期弹框,No changes to data, periods undone. Message no. 5A496 ]
最近在做组织信息增强,将子屏幕嵌入PPOME后,修改日期后会弹出信息框并重置300屏幕的开始日期.且PO13和PP01无异常 刚开始以为7000屏幕配置问题,但是对比后并没发现异常.跟踪消息号发现函数 ...
- nrm ls报错及npm镜像站点测速、切换
报错截图: 解决方法: 1.win键,搜索powershell,点击"以管理员身份运行" 2.粘贴下面命令,回车,敲y,回车 set-ExecutionPolicy RemoteS ...
- pytorch杂谈
inputs=tt.randn([10,3])可以随机生成高维度的数组 2. 定义一个模型为modle modle.cpu()将其调用到cpu modle.cuda()将其调用到gpu 3. 关于Cr ...
- Linux SMB传输文件命令
如何将linux服务器上的文件上传到华为NAS 如何登录华为NAS 首先登陆smb服务器, 不要账户名密码登录: smbclient -N \/\/192.168.0.1/共享 文件上传命令: 注意: ...
- DTO的理解
首要的作用,我认为就是减少原生对象的多余参数.包括为了安全,有时候也为了节约流量.例如:密码,你就不能返回到前端.因为不安全. 其次假如说:获取博客列表的时候,也不能返回博客全文吧.顶多就返回标题,i ...
- MSSQL T-SQL 基础 (创建、增、删、改)
1.创建数据库 create database StudentAchievementMS ----创建数据库,可以只执行此行来创建数据库,但以下属性都是默认 on primary --主数据文件 ( ...
- remove blank line
[$ cat all.experiments.csv.clean|sed -r '/^\s*$/d' > all.experiments.csv.clean2
- C语言 (数据结构)在顺序表中用二分查找和冒泡排序算法
main.c: #include <stdio.h> #include <stdlib.h> #include "SequenceList.h" int m ...
- NET 实现 Cron 定时任务执行,告别第三方组件
原文连接: (96条消息) NET 实现 Cron 定时任务执行,告别第三方组件_.net 定时任务_Phil Arist的博客-CSDN博客 代码: using System.Globalizati ...
- reduce处理相同id合并对象内容为数组
例: let arr = [ { situationId: '666666666666666666666', cloundClass: '999', } ...