Reinforce the Java Foundation (twenty-three) - Optional features of the new class Java8

I. Introduction

    Optional Optional class is a class with the same name Java8 null value determination in order to solve the problem, Reference Optional google guava class library introduced, to avoid the use of explicit class Optional null value determination (null defensive checks), to avoid the resulting null NPE (NullPointerException).

    Let's look at a piece of code:

    public static String getGender(Student student)
    {
        if(null == student)
        {
            return "Unkown";
        }
        return student.getGender();
        
    }

This is a way to get student sex, method to the Senate as a Student object, the object is to prevent student null, made a defensive check: If the value is null, return to "Unkown".

    Look at the use of the Optional optimization:

    public static String getGender(Student student)
    {
       return Optional.ofNullable(student).map(u -> u.getGender()).orElse("Unkown");
        
    }

    You can see, Optional type of binding lambda expressions used allows to develop code more simple and elegant.

Second, create Optional object

     We look like part of the source code Optional:

    private static final Optional<?> EMPTY = new Optional<>();

    private final T value;

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

    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

    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);
    }

As can be seen, two Optional class constructor is private type and therefore can not be displayed outside the class using the new new Optional () Optional way to create an object, but the class provides three Optional static method empty (), of ( T value), ofNullable (T value) Optinal objects to create, for example:

// 1、创建一个包装对象值为空的Optional对象
Optional<String> optStr = Optional.empty();
// 2、创建包装对象值非空的Optional对象
Optional<String> optStr1 = Optional.of("optional");
// 3、创建包装对象值允许为空的Optional对象
Optional<String> optStr2 = Optional.ofNullable(null);

Third, the use of typical interface class Optional

In the following some typical scenario as an example, lists common usage Optional API interface, along with the corresponding codes.

3.1 get () method

     Look simple get () method of the source code:

    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

Can be seen, get () method is mainly used for the actual value of the return package object, but if the wrapper object is null, an exception will be thrown NoSuchElementException.

3.2 isPresent () method

     isPresent () method Source:

    public boolean isPresent() {
        return value != null;
    }

Can be seen, isPresent () method for determining whether the object to be packaged non-null value. Here we look at some bad code:

    public static String getGender(Student student)
    {
        Optional<Student> stuOpt =  Optional.ofNullable(student);
        if(stuOpt.isPresent())
        {
            return stuOpt.get().getGender();
        }
        
        return "Unkown";
    }

This code is implemented in the first chapter (introduction) in a logical, but this usage is not diminished null defensive checking, and increased process Optional packaging, contrary to the Optional originally designed, so developers need to avoid this kind of bad use ~

3.3 ifPresent () method

     The IfPresent () method Source:

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

ifPresent () method accepts a Consumer objects (consumption function), if the value of the wrapped object is not empty, accept () method runs Consumer object. Examples are as follows:

    public static void printName(Student student)
    {
        Optional.ofNullable(student).ifPresent(u ->  System.out.println("The student name is : " + u.getName()));
    }

The example above used to print the student's name, due to internal ifPresent () method to do a null value checks, before calling without worrying about the NPE problem.

3.4 filter () method

     the filter () source:

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

filter () method takes as parameters Predicate object, an object for Optional filter, if they meet the conditions of Predicate returns Optional object itself, otherwise an empty Optional objects. For example as follows:

    public static void filterAge(Student student)
    {
        Optional.ofNullable(student).filter( u -> u.getAge() > 18).ifPresent(u ->  System.out.println("The student age is more than 18."));
    }

The above example, to achieve a student older than 18 screening.

3.5 map () method

     map () method of the source:

    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));
        }
    }

Parameter map () method of Function (function interface) objects, map () method of the object to be wrapped Optional calculates a function Function, and packaged into new Optional objects (object type of package may change). For example as follows:

    public static Optional<Integer> getAge(Student student)
    {
        return Optional.ofNullable(student).map(u -> u.getAge()); 
    }

The above code, the first () method is configured with ofNullable a Optional <Student> object, and then calculate the age of the students using map (), returns Optional <Integer> object (if the student is null, returns the map () method returns an empty Optinal Object).

3.6 flatMap () method

     flatMap () method Source:

    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));
        }
    }

With map () method is different, the reference function's return value Function type Optional <U> type, rather than U type, such flatMap () Optional objects capable of a two-dimensional map into a one-dimensional object. In function of example 3.5 as an example, faltMap () is rewritten as follows:

    public static Optional<Integer> getAge(Student student)
    {
        return Optional.ofNullable(student).flatMap(u -> Optional.ofNullable(u.getAge())); 
    }
3.7 orElse () method

     orElse () method Source:

    public T orElse(T other) {
        return value != null ? value : other;
    }

orElse () function is relatively simple method, i.e., non-null value if the object to be packaged, the packaging object value returned, otherwise the return value (default value) of the other parameters. As in the first chapter (profile) mentioned in the code:

    public static String getGender(Student student)
    {
       return Optional.ofNullable(student).map(u -> u.getGender()).orElse("Unkown");
        
    }
3.7 orElseGet () method

     orElseGet () method Source:

    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }

Similarly orElseGet () method orElse () method, except that orElseGet () method into an object reference to a Supplier, Supplier GET objects with the return value as a default value () method. Such as:

    public static String getGender(Student student)
    {
        return Optional.ofNullable(student).map(u -> u.getGender()).orElseGet(() -> "Unkown");      
    }
3.8 orElseThrow () method

     orElseThrow () method Source:

    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }

orElseThrow () method and actually orElseGet () method is very similar, and the parameters are Supplier objects, but orElseThrow () The Supplier must return a Throwable object is abnormal, and () will throw an exception in orElseThrow:

    public static String getGender1(Student student)
    {
        return Optional.ofNullable(student).map(u -> u.getGender()).orElseThrow(() -> new RuntimeException("Unkown"));      
    }

orElseThrow () method is suitable for packaging a particular subject in need thrown exception scene is empty.

IV Notes

    To be used with caution Optional Optional develop the proper use of "gestures", special attention not to use the wrong demonstration mentioned in Section 3.2, used with caution isPresent () and get () method, as much as possible the use of map (), filter (), orElse ( ) and other methods to play the role of Optional.

Guess you like

Origin www.cnblogs.com/tang-hao-/p/11644253.html