Optional类主要解决空指针异常NullPointerException。
Optional 类(java.util.Optional)是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。

创建Optional 对象

声明一个空的Optional

通过静态工厂方法Optional.empty(),创建一个空的Optional 对象,Optional中只有私有的构造方法,所以只能在其类中查找已经提供的创建方法,比如如下提供的一个容器中没有任何值的返回类型

public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}

使用方法:

Optional<Car> optCar = Optional.empty(); 

依据一个非空值创建Optional

使用静态工厂方法Optional.of(T),依据一个非空值创建一个Optional对象:

public static <T> Optional<T> of(T value) {
return new Optional<>(value);
} Optional<String> optCar = Optional.of("sdfs");

由于这种方法创建时,会new Optional(T t),而在new的过程中,私有的构造函数对其传入的变量有检验:

 private Optional(T value) {
this.value = Objects.requireNonNull(value);
}

当传入的参数为null时会爆NullPointerException

3. 可接受null的Optional

public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
Optional<Car> optCar = Optional.ofNullable(car);

如果car是null,那么得到的Optional对象就是个空对象。

读取Optional实例中的变量值

1. get()

如果此Optional中存在值,则返回该值,否则抛出NoSuchElementException。

public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}

比如:
Product构造函数(用于后面示例)

 public Product(Integer id, Integer num, BigDecimal price, String name, String category) {
this.id = id;
this.num = num;
this.price = price;
this.name = name;
this.category = category;
}
 Product prod = new Product(1, 1, new BigDecimal("15.5"), "面包", "零食");
Optional<Product> optProd = Optional.of(prod);
Optional<Product> optProdEmpty = Optional.empty();
Optional<Product> optProdNull = Optional.ofNullable(null);
Optional<Product> optProdDefault = Optional.ofNullable(prod);
System.out.println("optProd = " + optProd);
System.out.println("optProdEmpty = " + optProdEmpty);
System.out.println("optProdNull = " + optProdNull);
System.out.println("optProdDefault = " + optProdDefault);

输出结果:

optProd = Optional[com.bjmashibing.system.baierhu.stream.Product@23ab930d]
optProdEmpty = Optional.empty
optProdNull = Optional.empty
optProdDefault = Optional[com.bjmashibing.system.baierhu.stream.Product@23ab930d]

使用get获取值:只要是 Optional.empty,即Opention容器为null,就返回的是nullpointerException

2. orElse(T other)

public T orElse(T other) {
return value != null ? value : other;
}

调用该方法,如果Optional中为 null,则返回传入的值,否则会取出Optional中的具体值,这里可以做判空处理,即为null的时候如何处理问题

3. orElseGet(Supplier<? extends T> other)

orElseGet是orElse方法的延迟调用版,Supplier方法只有在Optional对象不含值时才执行调用。如果创建默认值是件耗时费力的工作,应该考虑采用这种方式(借此提升程序的性能),或者你需要非常确定某个方法仅在Optional为空时才进行调用,也可以考虑该方式(这种情况有严格的限制条件)

public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
 Optional<String> empty = Optional.ofNullable(null);
System.out.println(empty.orElse("There is no value present!"));
System.out.println(empty.orElseGet(()->{return "No value";}));

执行结果:

There is no value present!
No value

4. orElseThrow(Supplier<? extends X> exceptionSupplier)

orElseThrow和get方法非常类似,如果值存在,返回该值。如果Optional对象为空时都会抛出一个异常,但是使用orElseThrow你可以定制希 望抛出的异常类型。

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
//执行结果如下:
optProdEmpty.orElseThrow(() -> new ServiceException("ServiceException"));

//输出异常

java.lang.RuntimeException: ServiceException

at com.bjmashibing.system.baierhu.stream.OptionalTest.lambda$createOpentional$1(OptionalTest.java:20)
at java.util.Optional.orElseThrow(Optional.java:290)
at com.bjmashibing.system.baierhu.stream.OptionalTest.createOpentional(OptionalTest.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

5. ifPresent(Consumer<? super T> consumer)

在变量值存在时执行一个作为参数传入的方法,否则就不进行任何操作。

public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}

比如:

optProd.ifPresent(System.out::println);
optProd.ifPresent(item -> {
System.out.println(item.getName());
}
);

个人感觉就是打印一些信息而已,无实际作用

6.使用 isPresent()判断Optional 容器中是否包含对象

判断容器中是否包含值,用此方法可避免NoSuchElementException 异常。

public boolean isPresent() {
return value != null;
}

7.使用map从Optional对象中提取和转换值

 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));
}
}

比如:获取name值

//prodEmpty对象不知道是否为null
String name = null;
if(null != prodEmpty) {
name = prodEmpty.getName();
}else {
name = "test";
} //使用map
Optional<Product> optProd2 = Optional.ofNullable(prodEmpty);
name = optProdEmpty.map(Product::getName).orElse("test");

8.使用flatMap链接Optional对象

public class Product {
private Brand brand; public Brand getBrand() {
return brand;
} public void setBrand(Brand brand) {
this.brand = brand;
} public Optional<Brand> getBrandAsOptional(){
return Optional.ofNullable(brand);
}
} public class Brand {
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
Product prod = new Product(1L, 1, new BigDecimal("15.5"), "面包", "零食");
Brand brand = new Brand();
brand.setName("达利园");
prod.setBrand(brand); String brandName = optProd.flatMap(Product::getBrandAsOptional).map(Brand::getName).orElse("other");
System.out.println(brandName);

这种写法可以不用多重判断,前面为null时每个过程中返回的都是一个null的Optional

注意:在域模型中使用Optional,是无法序列化的。所以可以写一个get方法返回Optional类型。

9.使用filter剔除特定的值

filter方法接受一个谓词作为参数。如果Optional对象的值存在,并且它符合谓词的条件, filter方法就返回其值;否则它就返回一个空的Optional对象。

public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
Product prod = new Product(1, 1, new BigDecimal("15.5"), "面包", "零食");
Optional<Product>optProd=Optional.ofNullable(prod);
Optional<Product>pr=optProd.filter(item -> item.getNum() > 1);
System.out.println("pr = " + pr);

输出:pr = Optional.empty

总结:Optional类的方法

本文大多转载于:https://blog.csdn.net/u014231523/article/details/102649003

java8中的Optional的更多相关文章

  1. Java8中的Optional操作

    作者:汤圆 个人博客:javalover.cc 前言 官人们好啊,我是汤圆,今天给大家带来的是<Java8中的Optional操作>,希望有所帮助,谢谢 文章纯属原创,个人总结难免有差错, ...

  2. Java8 中的 Optional

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...

  3. 使用Java8中的Optional类来消除代码中的null检查

    简介 Optional类是Java 8新增的一个类,Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException). —— 每个 Java 程序员都非常了解的异常 ...

  4. Java8 中的 Optional 相关用法

    基本方法: ofNullable() 为可能 null 的值创建一个 Optional 实例,  然后可以对该实例遍历/过滤, 判断是否存在,或者为空时执行.. ifPresent(...) 如果值存 ...

  5. Java8 新特性 Optional 类

    Optional 类的简介   Optional类的是来自谷歌Guava的启发,然后就加入到Java8新特性中去了.Optional类主要就是为子决解价值亿万的错误,空指针异常.   Optional ...

  6. 一篇文章教会你使用Java8中的Lambda表达式

    简介 Java 8为开发者带来了许多重量级的新特性,包括Lambda表达式,流式数据处理,新的Optional类,新的日期和时间API等.这些新特性给Java开发者带来了福音,特别是Lambda表达式 ...

  7. Java8中的Stream API

    本篇文章继续介绍Java 8的另一个新特性——Stream API.新增的Stream API与InputStream和OutputStream是完全不同的概念,Stream API是对Java中集合 ...

  8. java8中的stream().filter()的使用和Optional()

    转: https://www.cnblogs.com/yimiyan/p/5992440.html Optional: https://www.cnblogs.com/zhangboyu/p/7580 ...

  9. java8中的map和reduce

    java8中的map和reduce 标签: java8函数式mapreduce 2014-06-19 19:14 10330人阅读 评论(4) 收藏 举报  分类: java(47)  FP(2)  ...

随机推荐

  1. 关于主机不能访问虚拟机的web服务解决

    centos7默认并没有开启80端口,我们只有开启就行 [root@localhost sysconfig]# firewall-cmd --permanent --add-port=3032/tcp ...

  2. LNMP配置——Nginx配置 —— Nginx的访问日志

    一.配置 先来看看Nginx的日志格式 #grep -A2 log_format /usr/local/nginx/conf/nginx.conf log_format combined_realip ...

  3. mysql最经典的语句

    一.基础1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份数 ...

  4. IDA 创建本地类型

    在IDA中我们常常使用 shift+F9打开结构体视图,ins 创建结构体,但操作有些繁琐. 我们可以在View-->Open Subviews-->Local Types(视图--> ...

  5. 【vue开发】 计算属性传参

    <template> <div> {{test('zhende', 'np')}} </div> </template> <script> ...

  6. 从零搭建一个IdentityServer——会话管理与登出

    在上一篇文章中我们介绍了单页应用是如何使用IdentityServer完成身份验证的,并且在讲到静默登录以及会话监听的时候都提到会话(Session)这一概念,会话指的是用户与系统之间交互过程,反过来 ...

  7. Docker系列——InfluxDB+Grafana+Jmeter性能监控平台搭建(二)

    在上一篇博文中,主要是讲了InfluxDB的配置,博文链接:https://www.cnblogs.com/hong-fithing/p/14453695.html,今天来分享下Jmeter的配置. ...

  8. (二)基于商品属性的相似商品推荐算法——Flink SQL实时计算实现商品的隐式评分

    系列随笔: (总览)基于商品属性的相似商品推荐算法 (一)基于商品属性的相似商品推荐算法--整体框架及处理流程 (二)基于商品属性的相似商品推荐算法--Flink SQL实时计算实现商品的隐式评分 ( ...

  9. 电梯也能无为而治——oo第二单元作业总结

    oo第二单元作业总结 一.设计策略与质量分析 第一次作业 设计策略 在第一次作业之前,我首先确定了生产者--消费者模式的大体架构,即由输入线程(可与主线程合并)充当生产者,电梯线程充当消费者,二者不直 ...

  10. canvas判断点是否在路径内

    应用场景 我们的项目中有个功能是,canvas上的某个图片选中后可以再这个图片上用鼠标拖拽绘制画笔线条. 当然绘制的边界要控制在图片大小范围内的,那么鼠标是可以随意动的,怎么能控制只在图片上的时候才绘 ...