1/* 2 * Copyright (C) 2011 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.google.common.base; 18 19import static com.google.common.base.Preconditions.checkNotNull; 20 21import com.google.common.annotations.Beta; 22import com.google.common.annotations.GwtCompatible; 23 24import java.io.Serializable; 25import java.util.Collections; 26import java.util.Iterator; 27import java.util.Set; 28 29import javax.annotation.Nullable; 30 31/** 32 * An immutable object that may contain a non-null reference to another object. Each 33 * instance of this type either contains a non-null reference, or contains nothing (in 34 * which case we say that the reference is "absent"); it is never said to "contain {@code 35 * null}". 36 * 37 * <p>A non-null {@code Optional<T>} reference can be used as a replacement for a nullable 38 * {@code T} reference. It allows you to represent "a {@code T} that must be present" and 39 * a "a {@code T} that might be absent" as two distinct types in your program, which can 40 * aid clarity. 41 * 42 * <p>Some uses of this class include 43 * 44 * <ul> 45 * <li>As a method return type, as an alternative to returning {@code null} to indicate 46 * that no value was available 47 * <li>To distinguish between "unknown" (for example, not present in a map) and "known to 48 * have no value" (present in the map, with value {@code Optional.absent()}) 49 * <li>To wrap nullable references for storage in a collection that does not support 50 * {@code null} (though there are 51 * <a href="http://code.google.com/p/guava-libraries/wiki/LivingWithNullHostileCollections"> 52 * several other approaches to this</a> that should be considered first) 53 * </ul> 54 * 55 * <p>A common alternative to using this class is to find or create a suitable 56 * <a href="http://en.wikipedia.org/wiki/Null_Object_pattern">null object</a> for the 57 * type in question. 58 * 59 * <p>This class is not intended as a direct analogue of any existing "option" or "maybe" 60 * construct from other programming environments, though it may bear some similarities. 61 * 62 * @param <T> the type of instance that can be contained. {@code Optional} is naturally 63 * covariant on this type, so it is safe to cast an {@code Optional<T>} to {@code 64 * Optional<S>} for any supertype {@code S} of {@code T}. 65 * @author Kurt Alfred Kluever 66 * @author Kevin Bourrillion 67 * @since 10.0 68 */ 69@Beta 70@GwtCompatible 71public abstract class Optional<T> implements Serializable { 72 /** 73 * Returns an {@code Optional} instance with no contained reference. 74 */ 75 @SuppressWarnings("unchecked") 76 public static <T> Optional<T> absent() { 77 return (Optional<T>) Absent.INSTANCE; 78 } 79 80 /** 81 * Returns an {@code Optional} instance containing the given non-null reference. 82 */ 83 public static <T> Optional<T> of(T reference) { 84 return new Present<T>(checkNotNull(reference)); 85 } 86 87 /** 88 * If {@code nullableReference} is non-null, returns an {@code Optional} instance containing that 89 * reference; otherwise returns {@link Optional#absent}. 90 */ 91 public static <T> Optional<T> fromNullable(@Nullable T nullableReference) { 92 return (nullableReference == null) 93 ? Optional.<T>absent() 94 : new Present<T>(nullableReference); 95 } 96 97 private Optional() {} 98 99 /** 100 * Returns {@code true} if this holder contains a (non-null) instance. 101 */ 102 public abstract boolean isPresent(); 103 104 /** 105 * Returns the contained instance, which must be present. If the instance might be 106 * absent, use {@link #or(Object)} or {@link #orNull} instead. 107 * 108 * @throws IllegalStateException if the instance is absent ({@link #isPresent} returns 109 * {@code false}) 110 */ 111 public abstract T get(); 112 113 /** 114 * Returns the contained instance if it is present; {@code defaultValue} otherwise. If 115 * no default value should be required because the instance is known to be present, use 116 * {@link #get()} instead. For a default value of {@code null}, use {@link #orNull}. 117 */ 118 public abstract T or(T defaultValue); 119 120 /** 121 * Returns this {@code Optional} if it has a value present; {@code secondChoice} 122 * otherwise. 123 */ 124 public abstract Optional<T> or(Optional<? extends T> secondChoice); 125 126 /** 127 * Returns the contained instance if it is present; {@code supplier.get()} otherwise. If the 128 * supplier returns {@code null}, a {@link NullPointerException} will be thrown. 129 * 130 * @throws NullPointerException if the supplier returns {@code null} 131 */ 132 public abstract T or(Supplier<? extends T> supplier); 133 134 /** 135 * Returns the contained instance if it is present; {@code null} otherwise. If the 136 * instance is known to be present, use {@link #get()} instead. 137 */ 138 @Nullable public abstract T orNull(); 139 140 /** 141 * Returns an immutable singleton {@link Set} whose only element is the 142 * contained instance if it is present; an empty immutable {@link Set} 143 * otherwise. 144 * 145 * @since 11.0 146 */ 147 public abstract Set<T> asSet(); 148 149 /** 150 * Returns {@code true} if {@code object} is an {@code Optional} instance, and either 151 * the contained references are {@linkplain Object#equals equal} to each other or both 152 * are absent. Note that {@code Optional} instances of differing parameterized types can 153 * be equal. 154 */ 155 @Override public abstract boolean equals(@Nullable Object object); 156 157 /** 158 * Returns a hash code for this instance. 159 */ 160 @Override public abstract int hashCode(); 161 162 /** 163 * Returns a string representation for this instance. The form of this string 164 * representation is unspecified. 165 */ 166 @Override public abstract String toString(); 167 168 /** 169 * Returns the value of each present instance from the supplied {@code optionals}, in order, 170 * skipping over occurrences of {@link Optional#absent}. Iterators are unmodifiable and are 171 * evaluated lazily. 172 * 173 * @since 11.0 174 */ 175 public static <T> Iterable<T> presentInstances(final Iterable<Optional<T>> optionals) { 176 checkNotNull(optionals); 177 return new Iterable<T>() { 178 @Override public Iterator<T> iterator() { 179 return new AbstractIterator<T>() { 180 private final Iterator<Optional<T>> iterator = checkNotNull(optionals.iterator()); 181 182 @Override protected T computeNext() { 183 while (iterator.hasNext()) { 184 Optional<T> optional = iterator.next(); 185 if (optional.isPresent()) { 186 return optional.get(); 187 } 188 } 189 return endOfData(); 190 } 191 }; 192 }; 193 }; 194 } 195 196 private static final long serialVersionUID = 0; 197 198 private static final class Present<T> extends Optional<T> { 199 private final T reference; 200 201 Present(T reference) { 202 this.reference = reference; 203 } 204 205 @Override public boolean isPresent() { 206 return true; 207 } 208 209 @Override public T get() { 210 return reference; 211 } 212 213 @Override public T or(T defaultValue) { 214 checkNotNull(defaultValue, "use orNull() instead of or(null)"); 215 return reference; 216 } 217 218 @Override public Optional<T> or(Optional<? extends T> secondChoice) { 219 checkNotNull(secondChoice); 220 return this; 221 } 222 223 @Override public T or(Supplier<? extends T> supplier) { 224 checkNotNull(supplier); 225 return reference; 226 } 227 228 @Override public T orNull() { 229 return reference; 230 } 231 232 @Override public Set<T> asSet() { 233 return Collections.singleton(reference); 234 } 235 236 @Override public boolean equals(@Nullable Object object) { 237 if (object instanceof Present) { 238 Present<?> other = (Present<?>) object; 239 return reference.equals(other.reference); 240 } 241 return false; 242 } 243 244 @Override public int hashCode() { 245 return 0x598df91c + reference.hashCode(); 246 } 247 248 @Override public String toString() { 249 return "Optional.of(" + reference + ")"; 250 } 251 252 private static final long serialVersionUID = 0; 253 } 254 255 private static final class Absent extends Optional<Object> { 256 private static final Absent INSTANCE = new Absent(); 257 258 @Override public boolean isPresent() { 259 return false; 260 } 261 262 @Override public Object get() { 263 throw new IllegalStateException("value is absent"); 264 } 265 266 @Override public Object or(Object defaultValue) { 267 return checkNotNull(defaultValue, "use orNull() instead of or(null)"); 268 } 269 270 @SuppressWarnings("unchecked") // safe covariant cast 271 @Override public Optional<Object> or(Optional<?> secondChoice) { 272 return (Optional) checkNotNull(secondChoice); 273 } 274 275 @Override public Object or(Supplier<?> supplier) { 276 return checkNotNull(supplier.get(), 277 "use orNull() instead of a Supplier that returns null"); 278 } 279 280 @Override @Nullable public Object orNull() { 281 return null; 282 } 283 284 @Override public Set<Object> asSet() { 285 return Collections.emptySet(); 286 } 287 288 @Override public boolean equals(@Nullable Object object) { 289 return object == this; 290 } 291 292 @Override public int hashCode() { 293 return 0x598df91c; 294 } 295 296 @Override public String toString() { 297 return "Optional.absent()"; 298 } 299 300 private Object readResolve() { 301 return INSTANCE; 302 } 303 304 private static final long serialVersionUID = 0; 305 } 306} 307