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 ...
随机推荐
- 微信小程序 - 超出文字省略组件
使用说明 sty:定义样式 text:文字 clamp: 0:代表不限制 1:超过1行省略号(默认) n:超过n行省略 点击下载:ellipsis
- python获取系统开机时间
import psutil import time time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(psutil.boot_time()))
- arm-linux 裸机下 VNC 的实现
这里的 arm-linux 裸机指的是,只有基本 C 库和安装了 busybox 的嵌入式系统,没有 X11 或者 wayland 作为底层支援. 这里的实现是基于 framebuffer 的,是将用 ...
- MVC+WCF框架下广告位管理——文件上传
广告位是站点中不可缺少的内容之中的一个.也是能直接给我们站点带来经济收益的内容之中的一个. 好的广告位不仅不会强宾压主,而会为我们的站点锦上添花.起到画龙点睛的作用.因此设计好广告位也是开发过程中一大 ...
- 取代Ant——Maven简介
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6625724.html 一:目前开发存在的问题 在没有Maven之前,我们开发一个项目,需要自行导入各种不同的 ...
- PHP视频学习一 mysql
设置mysql.exe文件目录到环境变量Path中去,可能在cmd下面使用mysql,wind7试了一下好像要重启以后才生效 什么是数据库 数据库就是存储数据的地方,是保存在计算机(硬盘/内存)中的数 ...
- C#程序实现窗体的最大化/最小化
C#程序实现窗体的最大化/最小化 http://blog.csdn.net/jiangqin115/article/details/41251215 private void button1_Clic ...
- Ubuntu 16.04 编译安装 ss
在网上没有找到合适的适合ubuntu的ss客户端, 考虑到ss的编译安装其实就带了ss-local这样的客户端, 于是在Ubuntu下编译安装了ss. 首先去github上下载最新的安装包 https ...
- Oracle常用方法
oracle常用函数整理 时间转换 to_char to_date select to_char( sysdate, 'yyyy-mm') FROM dual; -- 2014-05 select t ...
- xml中“ < > ”转义为“ < > ”问题处理
曾经也碰到过类似问题,解决方法是在发送或者解析报文前执行上面的方法将内容转义一下,现在我用dom4j组装如下的报文(报文体中内容传输时加密处理),大致介绍一下上面方法的使用,具体看代码. import ...