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) { Optionalgender = 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) { OptionalnonEmptyGender = 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) { Optionalgender = 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) { Optionalgender = 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) { Optionalgender = 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 Optionalresolution; 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 OptionaldisplayFeatures; // 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(Optionalmobile){ 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)