Рубрики
Без рубрики

Java 8 Опционально Подробно

– Java 8 Необязательный Углубленный

Java 8 представила новый класс, необязательный в пакете java.util. Он используется для представления значения присутствует или отсутствует. Главное преимущество этой новой конструкции заключается в том, что больше не будет слишком большого количества проверок null и Исключения NullPointerException . Это позволяет избежать любого исключения времени выполнения Nullpointerexception и поддерживает нас в разработке чистых и аккуратных API-интерфейсов Java или приложений. Подобно коллекциям и массивам, он также является контейнером для хранения не более одного значения. Давайте рассмотрим эту новую конструкцию на нескольких полезных примерах.

Преимущества Java 8 Опционально:

  1. Нулевые проверки не требуются.
  2. Больше никаких исключений NullPointerException во время выполнения.
  3. Мы можем разрабатывать чистые и аккуратные API.
  4. Больше никакого шаблонного кода

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(() -> "")); //

    }

}

Выход

MALE

MALE

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(Optional resolution) {
	this.resolution = resolution;
}

8.2 Тип возвращаемого метода

public Optional getResolution() {
	return resolution;
}

8.3 Параметр конструктора

public DisplayFeatures(String size, Optional resolution){
	this.size = size;
	this.resolution = resolution;
}

8.4 Объявление переменной

private Optional resolution;

8.5 Уровень класса

public class B

public class A> { }

Скачать Исходный Код

Рекомендации

  1. Необязательный JavaDoc

Оригинал: “https://mkyong.com/java8/java-8-optional-in-depth/”