An in depth analysis of Optional a new feature of java8

  • 2021-06-28 12:37:16
  • OfStack

Preface

Recently, the head fever has been very motivated to follow the source of java8, as well as obsession, guilt.

This paper takes jdk1.8.0_as an example111 source as an example


public final class Optional<T> {}

Optional is a container object that can contain objects or be empty in order to solve the NullPointerException design.Encapsulating many of the methods of air handling also adds retrieval tools like filter and map, where functional programming feels cool and explosive.

Basic Test Case Objects:


public class Java8OptionalTest {
 List<String> stringList = null;
 ICar car = new WeiLaiCar();
}

public class WeiLaiCar implements ICar {
 Integer wheels = new Integer(4);
 _ 

Four optionals available in Api

The core is the Optional object. The introduction of generics supports all object types and adds extensions to dubbointlong in common scenarios.Emphasis is placed on the method of Optional object under 1. The other three methods are similar.

public final class Optional < T > { public final class OptionalDouble { public final class OptionalInt { public final class OptionalLong {

@FunctionalInterface
PredicateConsumerSupplier All three interfaces are functional interfaces

Static method of


private Optional() {
 this.value = null;
}

The constructor is private, not new, but provides a static method such as of to initialize the class.


public static <T> Optional<T> of(T value) {
 return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
 return value == null ? empty() : of(value);
}
public static<T> Optional<T> empty() {
 @SuppressWarnings("unchecked")
 Optional<T> t = (Optional<T>) EMPTY;
 return t;
}

1. empty supports you to create an empty optional class, such a class directly get() will fail: java.util.NoSuchElementException: No value present

2. The object passed in by of (x) cannot be null, while ofNullable (x) is an object that supports the incoming null. 1 Generally, these two are used more.

present method

isPresent is used to determine whether an object in optional is null, and the ifPresent parameter is the lamdba expression executed when the object is not null.


public boolean isPresent() {
 return value != null;
}
public void ifPresent(Consumer<? super T> consumer) {
 if (value != null)
 consumer.accept(value);
}

The example details the ifPresent feature:


Java8OptionalTest test = new Java8OptionalTest();
Optional<Java8OptionalTest> optional = Optional.of(test);

pringTest(optional.isPresent());
//true
optional.ifPresent( a -> pringTest(a.getCar().getClass().getName()));
//com.ts.util.optional.WeiLaiCar
optional.ifPresent( a -> Optional.ofNullable(a.getStringList()).ifPresent(b -> pringTest("StringList:" + (b == null))));
// No. 1 Level ifPresent Is there test Object, so execute lambda Expression, while 2 Level ifPresent Of stringList yes null So no expression is executed 
optional.ifPresent( a -> Optional.ofNullable(a.getCar()).ifPresent(b -> pringTest("car:" + (b == null))));
//car:false
// No. 2 level ifPresent Of car The object exists, so the 2 Level expression executed 

map method

The source provides two types of map and flatMap.

The parameter of the map method is an lambda expression that is executed when the contained object is not null. It returns an encapsulated optional object that returns the result of the expression's execution, similarly supporting chain invocation, much like deep-going and recursive progression. The difference between flatMap is that the return of the lambda expression must actively wrap Optinoal, otherwise an error will be reported

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
 Objects.requireNonNull(mapper);
 if (!isPresent())
  return empty();
 else {
  return Optional.ofNullable(mapper.apply(value));
 }
}
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
 Objects.requireNonNull(mapper);
 if (!isPresent())
  return empty();
 else {
  return Objects.requireNonNull(mapper.apply(value));
 }
}

Test example:


Java8OptionalTest test = new Java8OptionalTest();
Optional<Java8OptionalTest> optional = Optional.of(test);

Optional opt1 = optional.map( a -> a.getCar());
pringTest(opt1.get());
//com.ts.util.optional.WeiLaiCar@5d6f64b1
int wheel = 0;// tradition null Judgment Writing 
if(test != null){
 if(test.getCar() != null){// The actual business may have more tiers than 3 layer 
  wheel = test.getCar().getWheelCount();
 }
}
pringTest(" tradition :"+wheel);
// tradition :4
Optional opt2 = optional.map( a -> a.getCar()).map(b -> b.getWheelCount());//Optional Supported Writing 
pringTest("optinal:"+opt2.get());
//optinal:4
Optional opt3 = optional.map( a -> a.getStringList()).map(b -> b.size());
pringTest(opt3);
//Optional.empty

Optional opt4 = optional.flatMap(a -> Optional.of(a.getCar()));// Active Packaging Optional object 
pringTest(opt4);
//Optional[com.ts.util.optional.WeiLaiCar@5d6f64b1]
Optional opt5 = optional.flatMap(a -> Optional.of(a.getCar())).flatMap(b -> Optional.ofNullable(b.getWheelCount()));
pringTest(opt5);
//Optional[4]

ES106 EN Method

The source code is as follows:


public Optional<T> filter(Predicate<? super T> predicate) {
 Objects.requireNonNull(predicate);
 if (!isPresent())
  return this;
 else
  return predicate.test(value) ? this : empty();
}

The filter method passes in an lambda expression for an assertion condition and returns an optional wrapper for an original object, thus supporting chain invocation.Just remember these three points and you will know how to use them.

Take the following example:


Java8OptionalTest test = new Java8OptionalTest();

Optional<Java8OptionalTest> optional = Optional.of(test);

Optional result = optional.filter( a -> a.getCar() != null).filter( b -> b.getClass().getName() != null);
pringTest(result.isPresent()? result.get().getClass().getName(): result.isPresent());
//com.ts.util.Java8OptionalTest
Optional result1 = optional.filter( a -> a.getStringList() != null);
pringTest(result1.get());
//java.util.NoSuchElementException: No value present

orElse method

Api provides three methods.

orElse returns this parameter when the object within optional is null, which is similar to many default settings. orElseGet is basically the same as orElse, except that the passed parameter supports lambda expression and returns the result of expression execution. orElseThrow is also passed in an lambda expression, but the expression throws an exception

public class Java8OptionalTest {
 List<String> stringList = null;
 ICar car = new WeiLaiCar();
}

public class WeiLaiCar implements ICar {
 Integer wheels = new Integer(4);
 _ 
0

For example:


public class Java8OptionalTest {
 List<String> stringList = null;
 ICar car = new WeiLaiCar();
}

public class WeiLaiCar implements ICar {
 Integer wheels = new Integer(4);
 _ 
1

summary

The official launch of Optional will never be a judgment for everyone. It is easy to think of three scenarios: null, filtermaporElse. Many business scenarios need to be explored and used slowly.Multifunctional usage needs to be mastered and technology is developing very rapidly.

There will be a special post on functional and Lambda expression usage, keeping an eye on my blog with curiosity.


Related articles: