Java 8 Optional In Depth
OptionalBasicExample.java
package com.mkyong;
import java.util.Optional;
public class OptionalBasicExample {
public static void main(String[] args) {
Optional<String> gender = Optional.of("MALE");
String answer1 = "Yes";
String answer2 = null;
System.out.println("Non-Empty Optional:" + gender);
System.out.println("Non-Empty Optional: Gender value : " + gender.get());
System.out.println("Empty Optional: " + Optional.empty());
System.out.println("ofNullable on Non-Empty Optional: " + Optional.ofNullable(answer1));
System.out.println("ofNullable on Empty Optional: " + Optional.ofNullable(answer2));
// java.lang.NullPointerException
System.out.println("ofNullable on Non-Empty Optional: " + Optional.of(answer2));
}
}
Output
Non-Empty Optional:Optional[MALE]
Non-Empty Optional: Gender value : MALE
Empty Optional: Optional.empty
ofNullable on Non-Empty Optional: Optional[Yes]
ofNullable on Empty Optional: Optional.empty
Exception in thread "main" java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.Optional.<init>(Optional.java:96)
at java.util.Optional.of(Optional.java:108)
//...
2. Optional.map and flatMap
package com.mkyong;
import java.util.Optional;
public class OptionalMapFlapMapExample {
public static void main(String[] args) {
Optional<String> nonEmptyGender = Optional.of("male");
Optional<String> emptyGender = Optional.empty();
System.out.println("Non-Empty Optional:: " + nonEmptyGender.map(String::toUpperCase));
System.out.println("Empty Optional :: " + emptyGender.map(String::toUpperCase));
Optional<Optional<String>> nonEmptyOtionalGender = Optional.of(Optional.of("male"));
System.out.println("Optional value :: " + nonEmptyOtionalGender);
System.out.println("Optional.map :: " + nonEmptyOtionalGender.map(gender -> gender.map(String::toUpperCase)));
System.out.println("Optional.flatMap :: " + nonEmptyOtionalGender.flatMap(gender -> gender.map(String::toUpperCase)));
}
}
Output
Non-Empty Optional:: Optional[MALE]
Empty Optional :: Optional.empty
Optional value :: Optional[Optional[male]]
Optional.map :: Optional[Optional[MALE]]
Optional.flatMap :: Optional[MALE]
3. Optional.filter
package com.mkyong;
import java.util.Optional;
public class OptionalFilterExample {
public static void main(String[] args) {
Optional<String> gender = Optional.of("MALE");
Optional<String> emptyGender = Optional.empty();
//Filter on Optional
System.out.println(gender.filter(g -> g.equals("male"))); //Optional.empty
System.out.println(gender.filter(g -> g.equalsIgnoreCase("MALE"))); //Optional[MALE]
System.out.println(emptyGender.filter(g -> g.equalsIgnoreCase("MALE"))); //Optional.empty
}
}
Output
Optional.empty
Optional[MALE]
Optional.empty
4. Optional isPresent and ifPresent
Optional.isPresent() returns true if the given Optional object is non-empty. Otherwise it returns false.
Optional.ifPresent() performs given action if the given Optional object is non-empty. Otherwise it returns false.
package com.mkyong;
import java.util.Optional;
public class OptionalIfPresentExample {
public static void main(String[] args) {
Optional<String> gender = Optional.of("MALE");
Optional<String> emptyGender = Optional.empty();
if (gender.isPresent()) {
System.out.println("Value available.");
} else {
System.out.println("Value not available.");
}
gender.ifPresent(g -> System.out.println("In gender Option, value available."));
//condition failed, no output print
emptyGender.ifPresent(g -> System.out.println("In emptyGender Option, value available."));
}
}
Output
Value available.
In gender Option, value available.
5. Optional orElse methods
It returns the value if present in Optional Container. Otherwise returns given default value.
package com.mkyong;
import java.util.Optional;
public class OptionalOrElseExample {
public static void main(String[] args) {
Optional<String> gender = Optional.of("MALE");
Optional<String> emptyGender = Optional.empty();
System.out.println(gender.orElse("<N/A>")); //MALE
System.out.println(emptyGender.orElse("<N/A>")); //<N/A>
System.out.println(gender.orElseGet(() -> "<N/A>")); //MALE
System.out.println(emptyGender.orElseGet(() -> "<N/A>")); //<N/A>
}
}
Output
MALE
<N/A>
MALE
<N/A>
6. Without Java 8 Optional
As everyone is familiar with Online Shopping. Let us assume that we want to implement a Mobile Product Module for a famous e-Commerce website.
Let us implement Mobile Domain module Without Java 8 Optional.
package com.mkyong.without.optional;
public class ScreenResolution {
private int width;
private int height;
public ScreenResolution(int width, int height){
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
package com.mkyong.without.optional;
public class DisplayFeatures {
private String size; // In inches
private ScreenResolution resolution;
public DisplayFeatures(String size, ScreenResolution resolution){
this.size = size;
this.resolution = resolution;
}
public String getSize() {
return size;
}
public ScreenResolution getResolution() {
return resolution;
}
}
package com.mkyong.without.optional;
public class Mobile {
private long id;
private String brand;
private String name;
private DisplayFeatures displayFeatures;
// Likewise we can see Memory Features, Camera Features etc.
public Mobile(long id, String brand, String name,
DisplayFeatures displayFeatures){
this.id = id;
this.brand = brand;
this.name = name;
this.displayFeatures = displayFeatures;
}
public long getId() {
return id;
}
public String getBrand() {
return brand;
}
public String getName() {
return name;
}
public DisplayFeatures getDisplayFeatures() {
return displayFeatures;
}
}
Here if we observe getMobileScreenWidth() method, it has lot of boiler plate code with lots null checks. Before Java 8, we should do all these non-sense stuff to avoid Runtime NullPointerExceptions.
package com.mkyong.without.optional;
public class MobileService {
public int getMobileScreenWidth(Mobile mobile){
if(mobile != null){
DisplayFeatures dfeatures = mobile.getDisplayFeatures();
if(dfeatures != null){
ScreenResolution resolution = dfeatures.getResolution();
if(resolution != null){
return resolution.getWidth();
}
}
}
return 0;
}
}
Develop one test application to test these Domain objects.
package com.mkyong.without.optional;
public class MobileTesterWithoutOptional {
public static void main(String[] args) {
ScreenResolution resolution = new ScreenResolution(750,1334);
DisplayFeatures dfeatures = new DisplayFeatures("4.7", resolution);
Mobile mobile = new Mobile(2015001, "Apple", "iPhone 6s", dfeatures);
MobileService mService = new MobileService();
int mobileWidth = mService.getMobileScreenWidth(mobile);
System.out.println("Apple iPhone 6s Screen Width = " + mobileWidth);
ScreenResolution resolution2 = new ScreenResolution(0,0);
DisplayFeatures dfeatures2 = new DisplayFeatures("0", resolution2);
Mobile mobile2 = new Mobile(2015001, "Apple", "iPhone 6s", dfeatures2);
int mobileWidth2 = mService.getMobileScreenWidth(mobile2);
System.out.println("Apple iPhone 16s Screen Width = " + mobileWidth2);
}
}
Output
Apple iPhone 6s Screen Width = 750
Apple iPhone 16s Screen Width = 0
7. With Java 8 Optional
Now develop same domain models using Java 8 Optional construct with clean and neat way.
P.S ScreenResolution.java no change. Please refer above section.
package com.mkyong.with.optional;
import java.util.Optional;
public class DisplayFeatures {
private String size; // In inches
private Optional<ScreenResolution> resolution;
public DisplayFeatures(String size, Optional<ScreenResolution> resolution){
this.size = size;
this.resolution = resolution;
}
public String getSize() {
return size;
}
public Optional<ScreenResolution> getResolution() {
return resolution;
}
}
package com.mkyong.with.optional;
import java.util.Optional;
public class Mobile {
private long id;
private String brand;
private String name;
private Optional<DisplayFeatures> displayFeatures;
// Like wise we can see MemoryFeatures, CameraFeatures etc.
// For simplicity, using only one Features
public Mobile(long id, String brand, String name, Optional<DisplayFeatures> displayFeatures){
this.id = id;
this.brand = brand;
this.name = name;
this.displayFeatures = displayFeatures;
}
public long getId() {
return id;
}
public String getBrand() {
return brand;
}
public String getName() {
return name;
}
public Optional<DisplayFeatures> getDisplayFeatures() {
return displayFeatures;
}
}
Here we can observe that how clean our getMobileScreenWidth() API without null checks and boiler plate code. We don not worry about NullPointerExceptions at run-time.
package com.mkyong.with.optional;
import java.util.Optional;
public class MobileService {
public Integer getMobileScreenWidth(Optional<Mobile> mobile){
return mobile.flatMap(Mobile::getDisplayFeatures)
.flatMap(DisplayFeatures::getResolution)
.map(ScreenResolution::getWidth)
.orElse(0);
}
}
Now develop one test component
package com.mkyong.with.optional;
import java.util.Optional;
public class MobileTesterWithOptional {
public static void main(String[] args) {
ScreenResolution resolution = new ScreenResolution(750,1334);
DisplayFeatures dfeatures = new DisplayFeatures("4.7", Optional.of(resolution));
Mobile mobile = new Mobile(2015001, "Apple", "iPhone 6s", Optional.of(dfeatures));
MobileService mService = new MobileService();
int width = mService.getMobileScreenWidth(Optional.of(mobile));
System.out.println("Apple iPhone 6s Screen Width = " + width);
Mobile mobile2 = new Mobile(2015001, "Apple", "iPhone 6s", Optional.empty());
int width2 = mService.getMobileScreenWidth(Optional.of(mobile2));
System.out.println("Apple iPhone 16s Screen Width = " + width2);
}
}
Output
Apple iPhone 6s Screen Width = 750
Apple iPhone 16s Screen Width = 0
8. Where does Java Optional fits?
If we observe above real-time Retail Domain use-case, we should know that Java Optional construct is useful at the following places.
8.1 Method Parameter
public void setResolution(Optional<ScreenResolution> resolution) {
this.resolution = resolution;
}
8.2 Method Return Type
public Optional<ScreenResolution> getResolution() {
return resolution;
}
8.3 Constructor Parameter
public DisplayFeatures(String size, Optional<ScreenResolution> resolution){
this.size = size;
this.resolution = resolution;
}
8.4 Variable Declaration
private Optional<ScreenResolution> resolution;
8.5 Class Level
public class B
public class A<T extends Optional<B>> { }
from http://www.mkyong.com/java8/java-8-optional-in-depth/
Java 8 Optional In Depth的更多相关文章
- JAVA 8 Optional类介绍及其源码
什么是Optional对象 Java 8中所谓的Optional对象,即一个容器对象,该对象可以包含一个null或非null值.如果该值不为null,则调用isPresent()方法将返回true,且 ...
- Java 8 Optional 类
转自:https://www.runoob.com/java/java8-optional-class.html Optional 类是一个可以为null的容器对象.如果值存在则isPresent() ...
- Java中Optional类的使用
从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...
- Java 8 新特性-菜鸟教程 (6) -Java 8 Optional 类
Java 8 Optional 类 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个容 ...
- jdk8新特性:在用Repository实体查询是总是提示要java.util.Optional, 原 Inferred type 'S' for type parameter 'S' is not within its bound;
jdk8新特性:在用Repository实体查询是总是提示要java.util.Optional 在使用springboot 方法报错: Inferred type 'S' for type para ...
- java中Optional和Stream流的部分操作
package test9; import java.util.DoubleSummaryStatistics; import java.util.Optional; import java.util ...
- Java 8 Optional 类深度解析
Java 8 Optional 类深度解析 身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只 ...
- Java 8 Optional类使用的实践经验
前言 Java中空指针异常(NPE)一直是令开发者头疼的问题.Java 8引入了一个新的Optional类,使用该类可以尽可能地防止出现空指针异常. Optional 类是一个可以为null的容器对象 ...
- Java 8 中的 java.util.Optional
Java 8 中的 java.util.Optional 学习了:https://blog.csdn.net/sun_promise/article/details/51362838 package ...
随机推荐
- C++ 第十二课 其它标准C函数
abort() 停止程序执行 assert() 当表达式非真,停止程序执行 atexit() 当程序退出执行设定的程序 bsearch() 执行折半查找 exit() 停止程序执行 getenv() ...
- 一个JAVA的WEB服务器事例
其实编写一个入门级别的JAVA的WEB服务器,很简单,用SOCKET类即可实现.相关内容可以参考:http://www.cnblogs.com/liqiu/p/3253022.html 一.首先创建一 ...
- MongoDB副本集配置系列一:安装MongoDB
1:下载MongoDB 2.6版本 https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-2.6.9.zip 2:解压 tar ...
- TOEIC真题学习
01.The old-fashioned delicatessen inside the street has become a popular place for lunch 街道里面的熟食店正在成 ...
- 通过ribbon 根据服务名获取所有服务实例的IP和端口列表
代码使用SpringCloud版本E3 业务场景: 今天遇到一个业务场景,要求根据服务名获取当前微服务集群中所有的对应服务实例的IP和端口,通过分析源码推算出了写法. 原理简述: 如果代码中引入了sp ...
- 完美解决office2013 错误1402
遇到1402问题 按照网络上的帖子都无法解决,老提示无权限更改,原来只是少了一个步骤而已!经本人多次试验,已经完美解决,现在上图! 步骤 肯定是得先出现错误,找到注册表所在项! 这个就不赘述,通过 ...
- Linux 破坏性修复
1.备份数据 [root@rhel6 ~]# dd count= + records in + records out bytes ( B) copied, 0.000181577 s, 2.8 MB ...
- 批处理转exe工具(Quick Batch File Compiler )|bat格式化exe
看到的,就是回忆.历史总是那么漫不经心,走完一生.留下可以记忆的脚本.... 对于window编写的bat脚本,想加密吗? 你所想的,前辈们基本上都有产出成果.所以在这个开源.共享.进步的互联网时代. ...
- Screen2EXE录屏|录制视频
Screen2EXE是一款具有独到压缩算法的屏幕录制软件,它可以记录用户在屏幕上的每一步操作,包括鼠标轨迹,点击动作给予花环提示,然后保存为不需播放器即可观看的exe可执行文件. 在生成录制文件的大小 ...
- ArcGIS空间参考概述
摘要:在地理数据库中,坐标系和其他相关空间属性被定义为各数据集的空间参考的一部分.空间参考是用于存储各要素类和栅格数据集,以及其他坐标属性(例如,x,y 坐标的坐标分辨率及可选的 z 坐标和测量 (m ...