JAVA之Optional类
Optional是JDK1.8之后出现的工具类,在此之前Google的gvaua工具包里就提供了这样的工具类,在集成到JDK之后对此进行了一些修改,同时使用了Objects类相关的代码,附上源码:
/* * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.util; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; /** * A container object which may or may not contain a non-null value. * If a value is present, {@code isPresent()} will return {@code true} and * {@code get()} will return the value. * ** * Here, {@code findFirst} returns an {@code OptionalAdditional methods that depend on the presence or absence of a contained * value are provided, such as {
@link #orElse(java.lang.Object) orElse()} * (return a default value if value not present) and * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block * of code if the value is present). * *This is a value-based * class; use of identity-sensitive operations (including reference equality * ({
@code ==}), identity hash code, or synchronization) on instances of * {@code Optional} may have unpredictable results and should be avoided. * * @since 1.8 */ public final class Optional{ /** * Common instance for {@code empty()}. */ private static final Optional<?> EMPTY = new Optional<>(); /** * If non-null, the value; if null, indicates no value is present */ private final T value; /** * Constructs an empty instance. * * @implNote Generally only one empty instance, {@link Optional#EMPTY}, * should exist per VM. */ private Optional() { this.value = null; } /** * Returns an empty {@code Optional} instance. No value is present for this * Optional. * * @apiNote Though it may be tempting to do so, avoid testing if an object * is empty by comparing with {@code ==} against instances returned by * {@code Option.empty()}. There is no guarantee that it is a singleton. * Instead, use {@link #isPresent()}. * * @param Type of the non-existent value * @return an empty {@code Optional} */ public staticOptional empty() { @SuppressWarnings("unchecked") Optional t = (Optional ) EMPTY; return t; } /** * Constructs an instance with the value present. * * @param value the non-null value to be present * @throws NullPointerException if value is null */ private Optional(T value) { this.value = Objects.requireNonNull(value); } /** * Returns an {@code Optional} with the specified present non-null value. * * @param the class of the value * @param value the value to be present, which must be non-null * @return an {@code Optional} with the value present * @throws NullPointerException if value is null */ public staticOptional of(T value) { return new Optional<>(value); } /** * Returns an {@code Optional} describing the specified value, if non-null, * otherwise returns an empty {@code Optional}. * * @param the class of the value * @param value the possibly-null value to describe * @return an {@code Optional} with a present value if the specified value * is non-null, otherwise an empty {@code Optional} */ public staticOptional ofNullable(T value) { return value == null ? empty() : of(value); } /** * If a value is present in this {@code Optional}, returns the value, * otherwise throws {@code NoSuchElementException}. * * @return the non-null value held by this {@code Optional} * @throws NoSuchElementException if there is no value present * * @see Optional#isPresent() */ public T get() { if (value == null) { throw new NoSuchElementException("No value present"); } return value; } /** * Return {@code true} if there is a value present, otherwise {@code false}. * * @return {@code true} if there is a value present, otherwise {@code false} */ public boolean isPresent() { return value != null; } /** * If a value is present, invoke the specified consumer with the value, * otherwise do nothing. * * @param consumer block to be executed if a value is present * @throws NullPointerException if value is present and {@code consumer} is * null */ public void ifPresent(Consumer<? super T> consumer) { if (value != null) consumer.accept(value); } /** * If a value is present, and the value matches the given predicate, * return an {@code Optional} describing the value, otherwise return an * empty {@code Optional}. * * @param predicate a predicate to apply to the value, if present * @return an {@code Optional} describing the value of this {@code Optional} * if a value is present and the value matches the given predicate, * otherwise an empty {@code Optional} * @throws NullPointerException if the predicate is null */ public Optional filter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); if (!isPresent()) return this; else return predicate.test(value) ? this : empty(); } /** * If a value is present, apply the provided mapping function to it, * and if the result is non-null, return an {@code Optional} describing the * result. Otherwise return an empty {@code Optional}. * * @apiNote This method supports post-processing on optional values, without * the need to explicitly check for a return status. For example, the * following code traverses a stream of file names, selects one that has * not yet been processed, and then opens that file, returning an * {@code Optional }: * * @code * Optional{fis = * names.stream().filter(name -> !isProcessedYet(name)) * .findFirst() * .map(name -> new FileInputStream(name)); * }
-
*
- it is also an {
有了Optional类之后,加上1.8之后的Lambada表达式,我们可以更好的进行链式编程,优化代码。