Optional use of class

[New features] Optional JAVA8

This is the practice to a new class of high school, when looking business bigwigs like to use the code found in this class, in particular, to study a bit.

  • Optional may be a container object is null: it can hold the value of type T, or just to save null.
  • If the value exists isPresent () method returns true, call the get () method returns the object.
  • Optional offers many useful ways, so we do not explicitly be null detection.
  • Optional introduction of class a good solution to a null pointer exception.

Source analysis:

1. The structure of the class constructor and
public final class Optional<T> {
    
    // 这个常量为后面调用 empty() 方法时实例化一个Optional对象做准备
    private static final Optional<?> EMPTY = new Optional<>();

    // 容器内部的值
    private final T value;

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

	private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
    // ...
}
2. empty () method

The static method generic generic type T is determined by the method of calling Optional, empty () method is very simple, like the constant EMPTY Optional cast to the same type of objects, and this empty () method Optional object returnedvalue is null

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

have a test:

	public static void main(String[] args){
        Optional<Integer> optional = Optional.empty();
        Integer i = optional.get();
        System.out.println(i);
    }

At this time, it will throw an exception: java.util.NoSuchElementException: No value present.
The reason is that, optional of Optional.empty created (after) value is null, when the get () method will determine whether the value is null, if null when the incorrect report. You can get a look at the source code () method.

3. get() / isEmpty() / isPresent() 方法

Relatively simple, put together.

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

	public boolean isEmpty() {
        return value == null;
    }

	public boolean isPresent() {
        return value != null;
    }
4. of(T value) / ofNullable(T value) 方法

By looking at the beginning of the source code can be found, Optional class will own two constructors fully privatized, then the public will certainly open ways for external access.

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

See the difference: When ofNullable (T value) L value creation may be null, of (T value) the value is not null .
See new Optional <> (value) for the constructor:

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

Continue to look Objects.requireNonNull (value) of the source code:

	public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

Direct throw an exception when null.

5. ifPresent () / ifPresentOrElse () method

Short answer to say, Consumer accept abstract class contains a method. The abstract method for processing incoming values, but no return value.

  • ifPresent (): If there is value to be treated, or not treated.
  • ifPresentOrElse () method: If the value there is to do treatment, or treatment with emptyAction.
    public void ifPresent(Consumer<? super T> action) {
        if (value != null) {
            action.accept(value);
        }
    }
    
    public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
        if (value != null) {
            action.accept(value);
        } else {
            emptyAction.run();
        }
    }
6. or() / orElse() / orElseGet() / orElseThrow() 方法

This method is used to value the.

    public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
        Objects.requireNonNull(supplier);
        if (isPresent()) {
            return this;
        } else {
            @SuppressWarnings("unchecked")
            Optional<T> r = (Optional<T>) supplier.get();
            return Objects.requireNonNull(r);
        }
    }
    
	public T orElse(T other) {
        return value != null ? value : other;
    }
    
    public T orElseGet(Supplier<? extends T> supplier) {
        return value != null ? value : supplier.get();
    }

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

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

Filtration values ​​are in line with requirements. If the value exists, filtered.

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

If the value there is a return stream contains only one value value.

	public Stream<T> stream() {
        if (!isPresent()) {
            return Stream.empty();
        } else {
            return Stream.of(value);
        }
    }

Basic reading the source code to know how to use. After still more of it. .

Reference Links: https://www.jianshu.com/p/dfdc3a0dacca

Published 33 original articles · won praise 9 · views 8695

Guess you like

Origin blog.csdn.net/Serena0814/article/details/97128601