Klasa Optional wprowadzona od Javy 8 umożliwia nam sprawdzenie, czy występuje null, bez pisania nadmiarowego kodu i uniknięcie częstego błędu NullPointerException.
Jest to generyczny pakiet, który umożliwia opakowanie zmiennej o wartości null.
Przykład:
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
//tworzymy Optional, który nie może być null za pomocą metody of()
Optional<String> optional1 = Optional.of("Optional.of()");
System.out.println(optional1.get());
//jezeli stworzymy optional z null:
//Optional<String> optional2 = Optional.of(null);//otrzymujemy błąd NullPointerException
//metoda nullable - może posiadać wartość lub bycnull
Optional<String> optional3 = Optional.ofNullable("Optional.ofNullable(\"Nie null\")");
System.out.println(optional3);
Optional<String> optional4 = Optional.ofNullable(null);
System.out.println("tu mamy null i zwróci: " + optional4 + ", nie ma błędu.");
//metoda empty tworząca pusty Optional
Optional<String> optional5 = Optional.empty();
System.out.println("pusty Optional zwróci: " + optional5 + ", nie ma błędu.");
//tworzymy Optionala i wykorzystamy jego metody
//tworzymy zmienną, która może mieć wartość lub null - nie wiemy co przechowuje
String str = String.valueOf(0);
//str=null; //spowosuje wyświetlenie komunikatu zmienna str jest null
Optional<String> optStr = Optional.ofNullable(str);
//pokaż kotku co masz w środku
if (optStr.isPresent()){
System.out.println(optStr.get());
} else {
System.out.println("zmienna str jest null");
}
//jeżeli wewnątrz Optionala jest wartość możemy wywołać lambdę
optStr.ifPresent( i -> System.out.println(i));
//referencja do metody
optStr.ifPresent(System.out::println);
//metoda map() pozwala na przekazanie funkcji jeżeli w obiekcie jest wartość, zwrócona wartość może być null
Integer integer = Integer.valueOf(0);
Optional<Integer> optInt = Optional.ofNullable(integer);
Optional<Integer> res = optInt.map(i -> i+1);
System.out.println(res);
System.out.println(res.get());
Integer integer1 = Integer.valueOf(0);
Optional<Integer> optInt1 = Optional.ofNullable(integer1);
optInt.map(i -> i+1)
.map(i -> i * 100)
.map(i -> i / 2)
.ifPresent(System.out::println);
Integer integer2 = null;
Optional<Integer> optIntNull = Optional.ofNullable(integer2);
Optional<Integer> resNull = optIntNull.map(i -> i+1);
System.out.println(resNull); //to nam zwróci Optional.empty
//System.out.println(resNull.get()); //ten zapis wygeneruje błąd: NoSuchElementException
//jeżeli chcemy zwrócić domyślną wartość jeżeli nasz Optional jest null, to korzystamy z orElse
System.out.println(resNull.orElse(666)); //ta wartość nie zostanie wyświetlona jeżeli optional nie będzie null
//filtrowanie Optional poprzez wyrażenie lambda, jeżeli warunek zostanie spełniony to optional przekazywany jest dalej, jeżeli nie to otrzymamy pusty obiekt
String str1 = "Nie pusty string";
Optional<String> optS = Optional.ofNullable(str1);
String test = optS.filter(s -> s.length() >0).orElse("Domyśny tekst");
System.out.println(test);
Optional<String> optS2 = Optional.ofNullable(null);
optS2.map(s -> s + "blablabla")
.filter(s -> s.length() >0)//jeżeli otional spełnia warunek to jest przekazywany dalej
.or( () -> Optional.ofNullable("Nowy domyślny tekst"))//metoda or podstawia domyślną wartość jeżeli pojawi się pusty Optional
.ifPresent(System.out::println);
//metoda or i referencje
String st = "Uwielbiam programować"; //zamień tekst na null
Optional<String> os = Optional.ofNullable(st);
String text = os.filter(s->s.length()>10)
.or( () -> Optional.ofNullable("mamy null"))
.map(String::toUpperCase)
.map(String::trim)
.orElse("i jestem tu");
System.out.println(text);
}
}