Optional in Java
Optional:
- In order to get rid of NullPointerException. Java8 introduced a new class in the java.util.Optional
- It is a container object , which value may or may not contain null value.
- It is a value based class , use of ==, identity hash code, synchronisation, may give unpredictable results and avoided.
- It is type safe way of dealing with values which might be null.
- It is elegant way of dealing with nulls in functional code.
- How we can prevent these null checks?
- To indicate that a method can return an actual value or null value, we can wrap the returned object in an Optional.
- It deals with null value at compile time level rather than at run time level.
- Runtime exceptions discovered in production become compile time concerns during development.
It contains some useful methods as below:
- public static <T> Optional<T> of(T value) ——> it can throw null pointer exception if value is null
- public static <T> Optional<T> ofNullable(T value)—>it returns empty Optional if value is null
Main difference is in usage:
of—> can throw null pointer exception if value is null
ofNullable—> does not throws null pointer exception but gives empty optional object.
- public T get()—> can throw NoSuchElementException if value is not present.
- public boolean isPresent() —> true=if value is present, false= if value is null
- public T orElse(T other)—> if value present returns the value, if value is null, then it can give default value passed in as argument
- public T orElseThrow()—> if value present returns value, if value is null throws an exception.
Optional<T>
Before Java8 developers had to carefully validate values because of possible of possibility of Null Pointer Exception (NPE) . All these were needed a error prone boilerplate code.
Optional<T> handles this issue of NPE and provides a predefined actions instead of throwing NPE.
Methods:
1. empty() : returns empty Optional instance
2. get(): If value present in this optional , returns value otherwise throws NPE
3. ifPresent() : returns true if value present else false
4. isPresent(Consumer other): if value present invokes specified consumer with value else do nothing
5. of( ): returns optional with non null value otherwise throws NPE
6. ofNullable() returns optional with value if not null otherwise returns empty Optional
7. orElse(T other) returns the value if present otherwise return other
8. orElseGet(Supplier other) return the value if present otherwise invokes other and returns NPE
9. OrElseThrow(Supplier exception) returns value if present otherwise exception is thrown
Creation of Optional:
1. Optional<String> optional = Optional.empty();
- It returns an empty Optional
2. String s = “sumit”;
Optional<String> optional = Optional.of(s);
- Returns an optional which contains non null value
3. Optional<String> optional = Optional.ofNullable(getValue());
- It returns Optional with a specific value or empty Optional if parameter is null
Usages:
eg1:
Before:
List<String> list = getList();
List<String> listString = list!= null? list: new ArrayList<>();
Using Java8
List<String> listString = getList().orElseGet( ()-> new ArrayList<>());
eg2:
Before:
User user = getUser();
if (user != null) {
Address address = user.getAddress();
if (address != null) {
String street = address.getStreet();
if (street != null) {
return street;
}
}
}
return "not specified";
Using Java8
Optional<User> user = Optional.ofNullable(getUser());
String result = user.map(User::getAddress)
.map(Address::getStreet)
.orElse("not specified");
Here we used map() methods to convert results to Optional<Address> and Optional<User>, here any of these methods return null then map() would return an empty Optional.
if getters of getAddress() and getStreet() return Optional<T> then we should use flatMap
eg3: Optional.orElseThrow()
String value = null;
Optional<String> valueOpt = Optional.ofNullable(value);
String result = valueOpt.orElseThrow(CustomException::new).toUpperCase();
Optional.ifPresentOrElse()
if (shoppingBasket.isPresent()) {
displayShoppingBasketContent(shoppingBasket.get());
} else {
displayEmptyShoppingBasket();
}
shoppingBasket.ifPresentOrElse(this::displayShoppingBasketContent, this::displayEmptyShoppingBasket);
Optional.or()
Optional<ShoppingBasket> shoppingBasket = findShoppingBasket().or(
() -> Optional.of(new ShoppingBasket("empty shopping basket")));
If value is present, method will return Optional describing the value, otherwise returns an Optional produced by the supplying function:
Mapping Optional Values:
We can map an optional value with map
eg1:
Optional<string> message = Optional.of(“message”);
Optional<string> oCapital = message.map(s->s.toUpperCase());
String value = oCapital.ge(); // MESSSAGE o/p
eg2:
Optional<Person> op = Optional.of(“”);
Optional<Integer> oAge = op.map(p->p.getAge());
eg3:
Optional<Person> oPerson = Optional.of(new Person(“John”, 35));
boolean isMiddleAge = oPerson.map(p->Person::getAge())
.filter(age -> age>= 13)
.filter(age<= 35)
.isPresent();
Comments
Post a Comment