Java 8 опционально по глубине
Java 8 представила новый класс Optional в пакете java.util. Используется для представления значения, присутствует или отсутствует. Основное преимущество этой новой конструкции состоит в том, что больше не нужно слишком много проверок на null иNullPointerException
. Он избегает использованияNullPointerExceptions
во время выполнения и поддерживает нас в разработке чистых и аккуратных Java API или приложений. Как и Коллекции и массивы, это также Контейнер для хранения не более одного значения. Давайте рассмотрим эту новую конструкцию с некоторыми полезными примерами.
Преимущества Java 8 Необязательно:
-
Нулевые проверки не требуются.
-
Нет больше NullPointerException во время выполнения.
-
Мы можем разработать чистые и аккуратные API.
-
Нет больше кода котельной плиты
1. Необязательный базовый пример
МетодOptional.ofNullable()
возвращает непустой Optional, если значение присутствует в данном объекте. В противном случае возвращает пустой Необязательно.
Метод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()
возвращает истину, если данный необязательный объект не пуст. В противном случае возвращается 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
Возвращает значение, если оно присутствует в дополнительном контейнере. В противном случае возвращает заданное значение по умолчанию.
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 Необязательно
Как все знакомы с интернет-магазинами. Предположим, мы хотим внедрить модуль мобильного продукта для известного веб-сайта электронной коммерции.
Давайте реализуем модуль Мобильный домен без 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()
, он имеет много шаблонного кода с множеством нулевых проверок. До Java 8 мы должны делать все эти бессмысленные вещи, чтобы избежать 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; } }
Разработайте одно тестовое приложение для тестирования этих объектов Домена.
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 Optional, аккуратно и аккуратно.
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; } }
Здесь мы можем наблюдать, как очистить наш APIgetMobileScreenWidth()
без нулевых проверок и кода шаблона. Мы не беспокоимся об исключениях NullPointerException во время выполнения.
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); } }
Теперь разработайте один тестовый компонент
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 полезна в следующих местах
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 КБ)