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) {
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. Необязательно. карта и плоская карта
package com.mkyong;
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. Необязательно.фильтр
package com.mkyong;
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() возвращает значение true, если данный необязательный объект не является пустым. В противном случае он возвращает значение false.
Необязательно. если присутствует() выполняет данное действие, если данный необязательный объект не является пустым. В противном случае он возвращает значение false.
package com.mkyong;
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
Он возвращает значение, если оно присутствует в дополнительном контейнере. В противном случае возвращает заданное значение по умолчанию.
package com.mkyong;
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 Необязательный
Как все знакомы с интернет-магазинами. Предположим, что мы хотим реализовать модуль мобильного продукта для известного веб-сайта электронной коммерции.
Давайте реализуем модуль Мобильного Домена Без Опциональной 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 Optional resolution;
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 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;
}
}
Здесь мы можем наблюдать, как очищается наш получить мобильную ширину экрана() API без нулевых проверок и кода котельной плиты. Мы не беспокоимся об исключении Nullpointerexception во время выполнения.
package com.mkyong.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);
}
}
Теперь разработайте один тестовый компонент
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/”