Java 8 en profondeur en option
Java 8 a introduit une nouvelle classe facultative dans le package java.util. Il est utilisé pour représenter une valeur présente ou absente. Le principal avantage de cette nouvelle construction est qu'il n'y a plus trop de vérifications nulles et deNullPointerException
. Il évite tout runtimeNullPointerExceptions
et nous aide à développer des API ou applications Java propres et soignées. Comme les collections et les tableaux, il s'agit également d'un conteneur contenant au plus une valeur. Explorons cette nouvelle construction avec quelques exemples utiles.
Avantages de Java 8 en option:
-
Aucun contrôle nul n'est requis.
-
Plus d'exception NullPointerException au moment de l'exécution.
-
Nous pouvons développer des API propres et soignées.
-
Plus de code de plaque de chaudière
1. Exemple de base facultatif
La méthodeOptional.ofNullable()
renvoie une option non vide si une valeur est présente dans l'objet donné. Sinon, renvoie vide Facultatif.
La méthodeOptionaal.empty()
est utile pour créer un objet facultatif vide.
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)); } }
Sortie
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))); } }
Sortie
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 } }
Sortie
Optional.empty Optional[MALE] Optional.empty
4. Facultatif isPresent et ifPresent
Optional.isPresent()
renvoie vrai si l'objet facultatif donné n'est pas vide. Sinon, elle renvoie faux.
Optional.ifPresent()
exécute une action donnée si l'objet optionnel donné n'est pas vide. Sinon, elle renvoie faux.
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.")); } }
Sortie
Value available. In gender Option, value available.
5. Méthodes orElse facultatives
Il renvoie la valeur si elle est présente dans le conteneur facultatif. Sinon, renvoie la valeur par défaut donnée.
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(() -> " ")); // } }
Sortie
MALEMALE
6. Sans Java 8 en option
Comme tout le monde connaît les achats en ligne. Supposons que nous voulons implémenter un module de produit mobile pour un célèbre site Web de commerce électronique.
Implémentons le module Mobile Domain sans Java 8 en option.
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; } }
Ici, si nous observons la méthodegetMobileScreenWidth()
, il y a beaucoup de code de plaque de chaudière avec beaucoup de vérifications nulles. Avant Java 8, nous devons faire toutes ces choses non sensées pour éviter les exceptions Runtime 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; } }
Développez une application de test pour tester ces objets de domaine.
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); } }
Sortie
Apple iPhone 6s Screen Width = 750 Apple iPhone 16s Screen Width = 0
7. Avec Java 8 en option
Développez maintenant les mêmes modèles de domaine à l'aide de la construction facultative Java 8 de manière propre et soignée.
P.S ScreenResolution.java
no change. Veuillez vous référer à la section ci-dessus.
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; } }
Ici, nous pouvons observer comment nettoyer notre APIgetMobileScreenWidth()
sans contrôle nul et code de plaque de chaudière. Nous ne nous inquiétons pas des NullPointerExceptions au moment de l'exécution.
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); } }
Développer maintenant un composant de test
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); } }
Sortie
Apple iPhone 6s Screen Width = 750 Apple iPhone 16s Screen Width = 0
8. Où se situe Java Optional?
Si nous observons le cas d'utilisation de Retail Domain en temps réel ci-dessus, nous devons savoir que la construction Java Optional est utile aux endroits suivants.
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> { }
Télécharger le code source
Télécharger -Java8Optional-example.zip (4 KB)