1 /*
   2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.util;
  26 
  27 import java.util.function.Consumer;
  28 import java.util.function.Function;
  29 import java.util.function.Predicate;
  30 import java.util.function.Supplier;
  31 
  32 /**
  33  * A container object which may or may not contain a non-null value.
  34  * If a value is present, {@code isPresent()} will return {@code true} and
  35  * {@code get()} will return the value.
  36  *
  37  * <p>Additional methods that depend on the presence or absence of a contained
  38  * value are provided, such as {@link #orElse(java.lang.Object) orElse()}
  39  * (return a default value if value not present) and
  40  * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block
  41  * of code if the value is present).
  42  *
  43  * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
  44  * class; use of identity-sensitive operations (including reference equality
  45  * ({@code ==}), identity hash code, or synchronization) on instances of
  46  * {@code Optional} may have unpredictable effects and should be avoided.
  47  *
  48  * @since 1.8
  49  */
  50 public final class Optional<T> {
  51     /**
  52      * Common instance for {@code empty()}.
  53      */
  54     private static final Optional<?> EMPTY = new Optional<>();
  55 
  56     /**
  57      * If non-null, the value; if null, indicates no value is present
  58      */
  59     private final T value;
  60 
  61     /**
  62      * Constructs an empty instance.
  63      *
  64      * @implNote Generally only one empty instance, {@link Optional#EMPTY},
  65      * should exist per VM.
  66      */
  67     private Optional() {
  68         this.value = null;
  69     }
  70 
  71     /**
  72      * Returns an empty {@code Optional} instance.  No value is present for this
  73      * Optional.
  74      *
  75      * @apiNote Though it may be tempting to do so, avoid testing if an object
  76      * is empty by comparing with {@code ==} against instances returned by
  77      * {@code Option.empty()}. There is no guarantee that it is a singleton.
  78      * Instead, use {@link #isPresent()}.
  79      *
  80      * @param <T> Type of the non-existent value
  81      * @return an empty {@code Optional}
  82      */
  83     public static<T> Optional<T> empty() {
  84         @SuppressWarnings("unchecked")
  85         Optional<T> t = (Optional<T>) EMPTY;
  86         return t;
  87     }
  88 
  89     /**
  90      * Constructs an instance with the value present.
  91      *
  92      * @param value the non-null value to be present
  93      * @throws NullPointerException if value is null
  94      */
  95     private Optional(T value) {
  96         this.value = Objects.requireNonNull(value);
  97     }
  98 
  99     /**
 100      * Returns an {@code Optional} with the specified present non-null value.
 101      *
 102      * @param <T> the class of the value
 103      * @param value the value to be present, which must be non-null
 104      * @return an {@code Optional} with the value present
 105      * @throws NullPointerException if value is null
 106      */
 107     public static <T> Optional<T> of(T value) {
 108         return new Optional<>(value);
 109     }
 110 
 111     /**
 112      * Returns an {@code Optional} describing the specified value, if non-null,
 113      * otherwise returns an empty {@code Optional}.
 114      *
 115      * @param <T> the class of the value
 116      * @param value the possibly-null value to describe
 117      * @return an {@code Optional} with a present value if the specified value
 118      * is non-null, otherwise an empty {@code Optional}
 119      */
 120     public static <T> Optional<T> ofNullable(T value) {
 121         return value == null ? empty() : of(value);
 122     }
 123 
 124     /**
 125      * If a value is present in this {@code Optional}, returns the value,
 126      * otherwise throws {@code NoSuchElementException}.
 127      *
 128      * @return the non-null value held by this {@code Optional}
 129      * @throws NoSuchElementException if there is no value present
 130      *
 131      * @see Optional#isPresent()
 132      */
 133     public T get() {
 134         if (value == null) {
 135             throw new NoSuchElementException("No value present");
 136         }
 137         return value;
 138     }
 139 
 140     /**
 141      * Return {@code true} if there is a value present, otherwise {@code false}.
 142      *
 143      * @return {@code true} if there is a value present, otherwise {@code false}
 144      */
 145     public boolean isPresent() {
 146         return value != null;
 147     }
 148 
 149     /**
 150      * If a value is present, invoke the specified consumer with the value,
 151      * otherwise do nothing.
 152      *
 153      * @param consumer block to be executed if a value is present
 154      * @throws NullPointerException if value is present and {@code consumer} is
 155      * null
 156      */
 157     public void ifPresent(Consumer<? super T> consumer) {
 158         if (value != null)
 159             consumer.accept(value);
 160     }
 161 
 162     /**
 163      * If a value is present, and the value matches the given predicate,
 164      * return an {@code Optional} describing the value, otherwise return an
 165      * empty {@code Optional}.
 166      *
 167      * @param predicate a predicate to apply to the value, if present
 168      * @return an {@code Optional} describing the value of this {@code Optional}
 169      * if a value is present and the value matches the given predicate,
 170      * otherwise an empty {@code Optional}
 171      * @throws NullPointerException if the predicate is null
 172      */
 173     public Optional<T> filter(Predicate<? super T> predicate) {
 174         Objects.requireNonNull(predicate);
 175         if (!isPresent())
 176             return this;
 177         else
 178             return predicate.test(value) ? this : empty();
 179     }
 180 
 181     /**
 182      * If a value is present, apply the provided mapping function to it,
 183      * and if the result is non-null, return an {@code Optional} describing the
 184      * result.  Otherwise return an empty {@code Optional}.
 185      *
 186      * @apiNote This method supports post-processing on optional values, without
 187      * the need to explicitly check for a return status.  For example, the
 188      * following code traverses a stream of file names, selects one that has
 189      * not yet been processed, and then opens that file, returning an
 190      * {@code Optional<FileInputStream>}:
 191      *
 192      * <pre>{@code
 193      *     Optional<FileInputStream> fis =
 194      *         names.stream().filter(name -> !isProcessedYet(name))
 195      *                       .findFirst()
 196      *                       .map(name -> new FileInputStream(name));
 197      * }</pre>
 198      *
 199      * Here, {@code findFirst} returns an {@code Optional<String>}, and then
 200      * {@code map} returns an {@code Optional<FileInputStream>} for the desired
 201      * file if one exists.
 202      *
 203      * @param <U> The type of the result of the mapping function
 204      * @param mapper a mapping function to apply to the value, if present
 205      * @return an {@code Optional} describing the result of applying a mapping
 206      * function to the value of this {@code Optional}, if a value is present,
 207      * otherwise an empty {@code Optional}
 208      * @throws NullPointerException if the mapping function is null
 209      */
 210     public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
 211         Objects.requireNonNull(mapper);
 212         if (!isPresent())
 213             return empty();
 214         else {
 215             return Optional.ofNullable(mapper.apply(value));
 216         }
 217     }
 218 
 219     /**
 220      * If a value is present, apply the provided {@code Optional}-bearing
 221      * mapping function to it, return that result, otherwise return an empty
 222      * {@code Optional}.  This method is similar to {@link #map(Function)},
 223      * but the provided mapper is one whose result is already an {@code Optional},
 224      * and if invoked, {@code flatMap} does not wrap it with an additional
 225      * {@code Optional}.
 226      *
 227      * @param <U> The type parameter to the {@code Optional} returned by
 228      * @param mapper a mapping function to apply to the value, if present
 229      *           the mapping function
 230      * @return the result of applying an {@code Optional}-bearing mapping
 231      * function to the value of this {@code Optional}, if a value is present,
 232      * otherwise an empty {@code Optional}
 233      * @throws NullPointerException if the mapping function is null or returns
 234      * a null result
 235      */
 236     public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
 237         Objects.requireNonNull(mapper);
 238         if (!isPresent())
 239             return empty();
 240         else {
 241             return Objects.requireNonNull(mapper.apply(value));
 242         }
 243     }
 244 
 245     /**
 246      * Return the value if present, otherwise return {@code other}.
 247      *
 248      * @param other the value to be returned if there is no value present, may
 249      * be null
 250      * @return the value, if present, otherwise {@code other}
 251      */
 252     public T orElse(T other) {
 253         return value != null ? value : other;
 254     }
 255 
 256     /**
 257      * Return the value if present, otherwise invoke {@code other} and return
 258      * the result of that invocation.
 259      *
 260      * @param other a {@code Supplier} whose result is returned if no value
 261      * is present
 262      * @return the value if present otherwise the result of {@code other.get()}
 263      * @throws NullPointerException if value is not present and {@code other} is
 264      * null
 265      */
 266     public T orElseGet(Supplier<? extends T> other) {
 267         return value != null ? value : other.get();
 268     }
 269 
 270     /**
 271      * Return the contained value, if present, otherwise throw an exception
 272      * to be created by the provided supplier.
 273      *
 274      * @apiNote A method reference to the exception constructor with an empty
 275      * argument list can be used as the supplier. For example,
 276      * {@code IllegalStateException::new}
 277      *
 278      * @param <X> Type of the exception to be thrown
 279      * @param exceptionSupplier The supplier which will return the exception to
 280      * be thrown
 281      * @return the present value
 282      * @throws X if there is no value present
 283      * @throws NullPointerException if no value is present and
 284      * {@code exceptionSupplier} is null
 285      */
 286     public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
 287         if (value != null) {
 288             return value;
 289         } else {
 290             throw exceptionSupplier.get();
 291         }
 292     }
 293 
 294     /**
 295      * Indicates whether some other object is "equal to" this Optional. The
 296      * other object is considered equal if:
 297      * <ul>
 298      * <li>it is also an {@code Optional} and;
 299      * <li>both instances have no value present or;
 300      * <li>the present values are "equal to" each other via {@code equals()}.
 301      * </ul>
 302      *
 303      * @param obj an object to be tested for equality
 304      * @return {code true} if the other object is "equal to" this object
 305      * otherwise {@code false}
 306      */
 307     @Override
 308     public boolean equals(Object obj) {
 309         if (this == obj) {
 310             return true;
 311         }
 312 
 313         if (!(obj instanceof Optional)) {
 314             return false;
 315         }
 316 
 317         Optional<?> other = (Optional<?>) obj;
 318         return Objects.equals(value, other.value);
 319     }
 320 
 321     /**
 322      * Returns the hash code value of the present value, if any, or 0 (zero) if
 323      * no value is present.
 324      *
 325      * @return hash code value of the present value or 0 if no value is present
 326      */
 327     @Override
 328     public int hashCode() {
 329         return Objects.hashCode(value);
 330     }
 331 
 332     /**
 333      * Returns a non-empty string representation of this Optional suitable for
 334      * debugging. The exact presentation format is unspecified and may vary
 335      * between implementations and versions.
 336      *
 337      * @implSpec If a value is present the result must include its string
 338      * representation in the result. Empty and present Optionals must be
 339      * unambiguously differentiable.
 340      *
 341      * @return the string representation of this instance
 342      */
 343     @Override
 344     public String toString() {
 345         return value != null
 346             ? String.format("Optional[%s]", value)
 347             : "Optional.empty";
 348     }
 349 }