Java 8 представила новый класс, необязательный в пакете java.util. Он используется для представления значения присутствует или отсутствует. Главное преимущество этой новой конструкции заключается в том, что больше не будет слишком большого количества проверок null и Исключения NullPointerException
. Это позволяет избежать любого исключения времени выполнения Nullpointerexception
и поддерживает нас в разработке чистых и аккуратных API-интерфейсов Java или приложений. Подобно коллекциям и массивам, он также является контейнером для хранения не более одного значения. Давайте рассмотрим эту новую конструкцию на нескольких полезных примерах.
Преимущества Java 8 Опционально:
- Нулевые проверки не требуются.
- Больше никаких исключений NullPointerException во время выполнения.
- Мы можем разрабатывать чистые и аккуратные API.
- Больше никакого шаблонного кода
1. Необязательный Базовый пример
Необязательный.ofnullable()
метод возвращает непустое необязательное значение, если значение присутствует в данном объекте. В противном случае возвращает пустое Необязательное значение.
Необязательно.Метод empty()
полезен для создания пустого необязательного объекта.
package com.mkyong; 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. Необязательно. карта и плоская карта
package com.mkyong; 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. Необязательно.фильтр
package com.mkyong; 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()
возвращает значение true, если данный необязательный объект не является пустым. В противном случае он возвращает значение false.
Необязательно. если присутствует()
выполняет данное действие, если данный необязательный объект не является пустым. В противном случае он возвращает значение false.
package com.mkyong; 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
Он возвращает значение, если оно присутствует в дополнительном контейнере. В противном случае возвращает заданное значение по умолчанию.
package com.mkyong; 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.
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; } }
Здесь, если мы рассмотрим метод get Mobile Screen Width()
, в нем много шаблонного кода с множеством нулевых проверок. До Java 8 мы должны делать все эти глупости, чтобы избежать исключения Nullpointerexception во время выполнения.
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; } }
Разработайте одно тестовое приложение для тестирования этих объектов домена.
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); } }
Выход
Apple iPhone 6s Screen Width = 750 Apple iPhone 16s Screen Width = 0
7. С Java 8 Необязательно
Теперь разрабатывайте те же модели предметной области, используя опциональную конструкцию Java 8 чистым и аккуратным способом.
P.S P.S никаких изменений. Пожалуйста, обратитесь к разделу выше.
package com.mkyong.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; } }
package com.mkyong.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; } }
Здесь мы можем наблюдать, как очищается наш получить мобильную ширину экрана()
API без нулевых проверок и кода котельной плиты. Мы не беспокоимся об исключении Nullpointerexception во время выполнения.
package com.mkyong.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); } }
Теперь разработайте один тестовый компонент
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); } }
Выход
Apple iPhone 6s Screen Width = 750 Apple iPhone 16s Screen Width = 0
8. Где подходит Java Optional?
Если мы рассмотрим приведенный выше пример использования домена розничной торговли в реальном времени, мы должны знать, что необязательная конструкция Java полезна в следующих местах.
8.1 Параметр метода
public void setResolution(Optionalresolution) { this.resolution = resolution; }
8.2 Тип возвращаемого метода
public OptionalgetResolution() { return resolution; }
8.3 Параметр конструктора
public DisplayFeatures(String size, Optionalresolution){ this.size = size; this.resolution = resolution; }
8.4 Объявление переменной
private Optionalresolution;
8.5 Уровень класса
public class B public class A> { }
Скачать Исходный Код
Рекомендации
Оригинал: “https://mkyong.com/java8/java-8-optional-in-depth/”