Java 8オプションの詳細
Java 8は、java.utilパッケージに新しいクラスOptionalを導入しました。 値の存在または不在を表すために使用されます。 この新しい構成の主な利点は、nullチェックとNullPointerExceptionが多すぎないことです。 ランタイムNullPointerExceptionsを回避し、クリーンでクリーンなJavaAPIまたはアプリケーションの開発をサポートします。 コレクションや配列と同様に、最大1つの値を保持するコンテナでもあります。 いくつかの有用な例を使用して、この新しい構成を調べてみましょう。
Java 8の利点オプション:
-
Nullチェックは不要です。
-
実行時にこれ以上NullPointerExceptionはありません。
-
クリーンできれいなAPIを開発できます。
-
これ以上ボイラープレートコード
1. オプションの基本的な例
Optional.ofNullable()メソッドは、指定されたオブジェクトに値が存在する場合、空でないオプションを返します。 それ以外の場合は空を返します。
Optionaal.empty()メソッドは、空のオプションオブジェクトを作成するのに役立ちます。
OptionalBasicExample.java
package com.example;
import java.util.Optional;
public class OptionalBasicExample {
public static void main(String[] args) {
Optional 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));
}
}
出力
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.(Optional.java:96)
at java.util.Optional.of(Optional.java:108)
//...
2. Optional.map and flatMap
OptionalMapFlapMapExample.java
package com.example;
import java.util.Optional;
public class OptionalMapFlapMapExample {
public static void main(String[] args) {
Optional nonEmptyGender = Optional.of("male");
Optional emptyGender = Optional.empty();
System.out.println("Non-Empty Optional:: " + nonEmptyGender.map(String::toUpperCase));
System.out.println("Empty Optional :: " + emptyGender.map(String::toUpperCase));
Optional> 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)));
}
}
出力
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
OptionalFilterExample.java
package com.example;
import java.util.Optional;
public class OptionalFilterExample {
public static void main(String[] args) {
Optional gender = Optional.of("MALE");
Optional 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
}
}
出力
Optional.empty Optional[MALE] Optional.empty
4. オプションのisPresentおよびifPresent
指定されたオプションオブジェクトが空でない場合、Optional.isPresent()はtrueを返します。 そうでなければfalseを返します。
Optional.ifPresent()は、指定されたオプションオブジェクトが空でない場合、指定されたアクションを実行します。 そうでなければfalseを返します。
OptionalIfPresentExample.java
package com.example;
import java.util.Optional;
public class OptionalIfPresentExample {
public static void main(String[] args) {
Optional gender = Optional.of("MALE");
Optional 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."));
}
}
出力
Value available. In gender Option, value available.
5. オプションのorElseメソッド
Optional Containerに存在する場合、値を返します。 それ以外の場合、指定されたデフォルト値を返します。
OptionalOrElseExample.java
package com.example;
import java.util.Optional;
public class OptionalOrElseExample {
public static void main(String[] args) {
Optional gender = Optional.of("MALE");
Optional emptyGender = Optional.empty();
System.out.println(gender.orElse("")); //MALE
System.out.println(emptyGender.orElse("")); //
System.out.println(gender.orElseGet(() -> "")); //MALE
System.out.println(emptyGender.orElseGet(() -> "")); //
}
}
出力
MALEMALE
6. Java 8オプションなし
誰もがオンラインショッピングに精通しているからです。 有名なeコマースWebサイト用のモバイル製品モジュールを実装するとします。
Java 8オプションなしでモバイルドメインモジュールを実装しましょう。
ScreenResolution.java
package com.example.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;
}
}
DisplayFeatures.java
package com.example.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;
}
}
Mobile.java
package com.example.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;
}
}
ここで、getMobileScreenWidth()メソッドを観察すると、多くのnullチェックを含む多くのボイラープレートコードがあります。 Java 8より前のバージョンでは、ランタイムNullPointerExceptionsを回避するために、これらすべての意味のないことを行う必要があります。
MobileService.java
package com.example.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;
}
}
これらのDomainオブジェクトをテストするテストアプリケーションを1つ開発します。
MobileTesterWithoutOptional.java
package com.example.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);
}
}
出力
Apple iPhone 6s Screen Width = 750 Apple iPhone 16s Screen Width = 0
7. Java 8オプション付き
今度は、Java 8オプションの構成を使用して、きれいできれいな方法で同じドメインモデルを開発します。
P.S ScreenResolution.java no change. 上記のセクションを参照してください。
DisplayFeatures.java
package com.example.with.optional;
import java.util.Optional;
public class DisplayFeatures {
private String size; // In inches
private Optional resolution;
public DisplayFeatures(String size, Optional resolution){
this.size = size;
this.resolution = resolution;
}
public String getSize() {
return size;
}
public Optional getResolution() {
return resolution;
}
}
Mobile.java
package com.example.with.optional;
import java.util.Optional;
public class Mobile {
private long id;
private String brand;
private String name;
private Optional 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){
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 getDisplayFeatures() {
return displayFeatures;
}
}
ここでは、nullチェックとボイラープレートコードなしでgetMobileScreenWidth()APIがどれほどクリーンであるかを観察できます。 実行時のNullPointerExceptionsについて心配する必要はありません。
MobileService.java
package com.example.with.optional;
import java.util.Optional;
public class MobileService {
public Integer getMobileScreenWidth(Optional mobile){
return mobile.flatMap(Mobile::getDisplayFeatures)
.flatMap(DisplayFeatures::getResolution)
.map(ScreenResolution::getWidth)
.orElse(0);
}
}
1つのテストコンポーネントを開発する
MobileTesterWithOptional.java
package com.example.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);
}
}
出力
Apple iPhone 6s Screen Width = 750 Apple iPhone 16s Screen Width = 0
8. Java Optionalはどこに適合しますか?
上記のリアルタイム小売ドメインのユースケースを観察する場合、Java Optionalコンストラクトが次の場所で役立つことを知っておく必要があります。
8.1 Method Parameter
public void setResolution(Optionalresolution) { this.resolution = resolution; }
8.2 Method Return Type
public OptionalgetResolution() { return resolution; }
8.3 Constructor Parameter
public DisplayFeatures(String size, Optionalresolution){ this.size = size; this.resolution = resolution; }
8.4 Variable Declaration
private Optionalresolution;
8.5 Class Level
public class B public class A> { }
ソースコードをダウンロード
ダウンロード–Java8Optional-example.zip(4 KB)