Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one or more
0003  * contributor license agreements.  See the NOTICE file distributed with
0004  * this work for additional information regarding copyright ownership.
0005  * The ASF licenses this file to You under the Apache License, Version 2.0
0006  * (the "License"); you may not use this file except in compliance with
0007  * the License.  You may obtain a copy of the License at
0008  *
0009  *    http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  */
0017 
0018 package org.apache.spark.api.java;
0019 
0020 import java.io.Serializable;
0021 import java.util.Objects;
0022 
0023 import com.google.common.base.Preconditions;
0024 
0025 /**
0026  * <p>Like {@code java.util.Optional} in Java 8, {@code scala.Option} in Scala, and
0027  * {@code com.google.common.base.Optional} in Google Guava, this class represents a
0028  * value of a given type that may or may not exist. It is used in methods that wish
0029  * to optionally return a value, in preference to returning {@code null}.</p>
0030  *
0031  * <p>In fact, the class here is a reimplementation of the essential API of both
0032  * {@code java.util.Optional} and {@code com.google.common.base.Optional}. From
0033  * {@code java.util.Optional}, it implements:</p>
0034  *
0035  * <ul>
0036  *   <li>{@link #empty()}</li>
0037  *   <li>{@link #of(Object)}</li>
0038  *   <li>{@link #ofNullable(Object)}</li>
0039  *   <li>{@link #get()}</li>
0040  *   <li>{@link #orElse(Object)}</li>
0041  *   <li>{@link #isPresent()}</li>
0042  * </ul>
0043  *
0044  * <p>From {@code com.google.common.base.Optional} it implements:</p>
0045  *
0046  * <ul>
0047  *   <li>{@link #absent()}</li>
0048  *   <li>{@link #of(Object)}</li>
0049  *   <li>{@link #fromNullable(Object)}</li>
0050  *   <li>{@link #get()}</li>
0051  *   <li>{@link #or(Object)}</li>
0052  *   <li>{@link #orNull()}</li>
0053  *   <li>{@link #isPresent()}</li>
0054  * </ul>
0055  *
0056  * <p>{@code java.util.Optional} itself was not used because at the time, the
0057  * project did not require Java 8. Using {@code com.google.common.base.Optional}
0058  * has in the past caused serious library version conflicts with Guava that can't
0059  * be resolved by shading. Hence this work-alike clone.</p>
0060  *
0061  * @param <T> type of value held inside
0062  */
0063 public final class Optional<T> implements Serializable {
0064 
0065   private static final Optional<?> EMPTY = new Optional<>();
0066 
0067   private final T value;
0068 
0069   private Optional() {
0070     this.value = null;
0071   }
0072 
0073   private Optional(T value) {
0074     Preconditions.checkNotNull(value);
0075     this.value = value;
0076   }
0077 
0078   // java.util.Optional API (subset)
0079 
0080   /**
0081    * @return an empty {@code Optional}
0082    */
0083   public static <T> Optional<T> empty() {
0084     @SuppressWarnings("unchecked")
0085     Optional<T> t = (Optional<T>) EMPTY;
0086     return t;
0087   }
0088 
0089   /**
0090    * @param value non-null value to wrap
0091    * @return {@code Optional} wrapping this value
0092    * @throws NullPointerException if value is null
0093    */
0094   public static <T> Optional<T> of(T value) {
0095     return new Optional<>(value);
0096   }
0097 
0098   /**
0099    * @param value value to wrap, which may be null
0100    * @return {@code Optional} wrapping this value, which may be empty
0101    */
0102   public static <T> Optional<T> ofNullable(T value) {
0103     if (value == null) {
0104       return empty();
0105     } else {
0106       return of(value);
0107     }
0108   }
0109 
0110   /**
0111    * @return the value wrapped by this {@code Optional}
0112    * @throws NullPointerException if this is empty (contains no value)
0113    */
0114   public T get() {
0115     Preconditions.checkNotNull(value);
0116     return value;
0117   }
0118 
0119   /**
0120    * @param other value to return if this is empty
0121    * @return this {@code Optional}'s value if present, or else the given value
0122    */
0123   public T orElse(T other) {
0124     return value != null ? value : other;
0125   }
0126 
0127   /**
0128    * @return true iff this {@code Optional} contains a value (non-empty)
0129    */
0130   public boolean isPresent() {
0131     return value != null;
0132   }
0133 
0134   // Guava API (subset)
0135   // of(), get() and isPresent() are identically present in the Guava API
0136 
0137   /**
0138    * @return an empty {@code Optional}
0139    */
0140   public static <T> Optional<T> absent() {
0141     return empty();
0142   }
0143 
0144   /**
0145    * @param value value to wrap, which may be null
0146    * @return {@code Optional} wrapping this value, which may be empty
0147    */
0148   public static <T> Optional<T> fromNullable(T value) {
0149     return ofNullable(value);
0150   }
0151 
0152   /**
0153    * @param other value to return if this is empty
0154    * @return this {@code Optional}'s value if present, or else the given value
0155    */
0156   public T or(T other) {
0157     return value != null ? value : other;
0158   }
0159 
0160   /**
0161    * @return this {@code Optional}'s value if present, or else null
0162    */
0163   public T orNull() {
0164     return value;
0165   }
0166 
0167   // Common methods
0168 
0169   @Override
0170   public boolean equals(Object obj) {
0171     if (!(obj instanceof Optional)) {
0172       return false;
0173     }
0174     Optional<?> other = (Optional<?>) obj;
0175     return Objects.equals(value, other.value);
0176   }
0177 
0178   @Override
0179   public int hashCode() {
0180     return value == null ? 0 : value.hashCode();
0181   }
0182 
0183   @Override
0184   public String toString() {
0185     return value == null ? "Optional.empty" : String.format("Optional[%s]", value);
0186   }
0187 
0188 }