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 ...
随机推荐
- 重设域管理员密码-window server 2008 R2
How to Reset Your Forgotten Domain Admin Password on Server 2008 R2 Forgetting your password is alwa ...
- eclipse 运行简单JAVA程序事例
开发JAVA已经有一段时间了,不过要运行JAVA程序,还是在命令行敲命令,很不方便,很麻烦,突然想到eclipse应该也有这个功能,于是百度了一下,将步骤晒出来,供大家参考. 1.创建JAVA工程 单 ...
- MAC快捷方式记录
刚刚转到MAC,很多功能发现不能用,总结一下: 刷新页面:command+r 命令行,到行首:control+a 命令行,到行尾:control+e vim,到行尾:shift+$ vim,到行首:s ...
- 手把手教你从零实现Linux misc设备驱动一(基于友善之臂4412开发板)
关于怎样来写一个misc设备,在前面有篇文章已经介绍了大致的流程,如今就让我们来实现一个最简单的misc设备驱动. http://blog.csdn.net/morixinguan/article/d ...
- django之创建第12个项目-加载图片
百度云盘:django之创建第12个项目-加载图片 1.setting配置 #静态文件相关配置 # URL prefix for static files. # Example: "http ...
- MBTiles 1.2 规范翻译
MBTiles 1.2 可以参考超图的文档MBTiles扩展 具体实现可以参考浅谈利用SQLite存储离散瓦片的思路和实现方法 mapbox提供了一个简单实现测试代码,github地址在这里https ...
- Docker Swarm Mode无法增加管理节点
这两天用Docker Swarm Mode,加入新的管理节点会报以下错误(在/var/log/messages文件中可以看到): Handler for POST /v1.37/swarm/join ...
- Effective前端(3)用CSS画一个三角形
来源:https://zhuanlan.zhihu.com/p/26160325 三角形的场景很常见,打开一个页面可以看到各种各样的三角形: 由于div一般是四边形,要画个三角形并不是那么直观.你可以 ...
- vmware安装找不到虚拟网卡解决方案
前一段实际,win7升级到win10发现vmware12没有虚拟网卡vnet1/vnet8.这不坑爹吗,没网卡能通信吗? 在网上搜寻一下发现可以重置网络,即可再次安装虚拟网卡...算是对问题的记录学习 ...
- windows DLL中使用COM的注意事项
windows的DLL开发是有需要注意的地方的,不然会造成一些问题.由于我最近的使用不当,又造成了问题,虽然之前有写过一篇笔记, http://www.cnblogs.com/foohack/p/66 ...