/*
* Copyright (C) 2011 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.common.base;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.Nullable;
An immutable object that may contain a non-null reference to another object. Each instance of this type either contains a non-null reference, or contains nothing (in which case we say that the reference is "absent"); it is never said to "contain null
". A non-null Optional<T>
reference can be used as a replacement for a nullable T
reference. It allows you to represent "a T
that must be present" and a "a T
that might be absent" as two distinct types in your program, which can aid clarity.
Some uses of this class include
- As a method return type, as an alternative to returning
null
to indicate that no value was available - To distinguish between "unknown" (for example, not present in a map) and "known to have no value" (present in the map, with value
Optional.absent()
) - To wrap nullable references for storage in a collection that does not support
null
(though there are several other
approaches to this that should be considered first)
A common alternative to using this class is to find or create a suitable null object for the type in question.
This class is not intended as a direct analogue of any existing "option" or "maybe" construct
from other programming environments, though it may bear some similarities.
Comparison to java.util.Optional
(JDK 8 and higher): A new Optional
class was added for Java 8. The two classes are extremely similar, but incompatible (they cannot share a common supertype). All known differences are listed either here or with the
relevant methods below.
- This class is serializable;
java.util.Optional
is not. java.util.Optional
has the additional methods ifPresent
, filter
, flatMap
, and orElseThrow
. java.util
offers the primitive-specialized versions OptionalInt
,
OptionalLong
and OptionalDouble
, the use of which is recommended; Guava does not have these.
There are no plans to deprecate this class in the foreseeable future. However, we do
gently recommend that you prefer the new, standard Java class whenever possible.
See the Guava User Guide article on using
Optional
.
Author: Kurt Alfred Kluever, Kevin Bourrillion Type parameters: - <T> – the type of instance that can be contained.
Optional
is naturally covariant on this type, so it is safe to cast an Optional<T>
to Optional<S>
for any supertype S
of T
.
Since: 10.0
/**
* An immutable object that may contain a non-null reference to another object. Each instance of
* this type either contains a non-null reference, or contains nothing (in which case we say that
* the reference is "absent"); it is never said to "contain {@code null}".
*
* <p>A non-null {@code Optional<T>} reference can be used as a replacement for a nullable {@code T}
* reference. It allows you to represent "a {@code T} that must be present" and a "a {@code T} that
* might be absent" as two distinct types in your program, which can aid clarity.
*
* <p>Some uses of this class include
*
* <ul>
* <li>As a method return type, as an alternative to returning {@code null} to indicate that no
* value was available
* <li>To distinguish between "unknown" (for example, not present in a map) and "known to have no
* value" (present in the map, with value {@code Optional.absent()})
* <li>To wrap nullable references for storage in a collection that does not support {@code null}
* (though there are <a
* href="https://github.com/google/guava/wiki/LivingWithNullHostileCollections">several other
* approaches to this</a> that should be considered first)
* </ul>
*
* <p>A common alternative to using this class is to find or create a suitable <a
* href="http://en.wikipedia.org/wiki/Null_Object_pattern">null object</a> for the type in question.
*
* <p>This class is not intended as a direct analogue of any existing "option" or "maybe" construct
* from other programming environments, though it may bear some similarities.
*
* <p><b>Comparison to {@code java.util.Optional} (JDK 8 and higher):</b> A new {@code Optional}
* class was added for Java 8. The two classes are extremely similar, but incompatible (they cannot
* share a common supertype). <i>All</i> known differences are listed either here or with the
* relevant methods below.
*
* <ul>
* <li>This class is serializable; {@code java.util.Optional} is not.
* <li>{@code java.util.Optional} has the additional methods {@code ifPresent}, {@code filter},
* {@code flatMap}, and {@code orElseThrow}.
* <li>{@code java.util} offers the primitive-specialized versions {@code OptionalInt}, {@code
* OptionalLong} and {@code OptionalDouble}, the use of which is recommended; Guava does not
* have these.
* </ul>
*
* <p><b>There are no plans to deprecate this class in the foreseeable future.</b> However, we do
* gently recommend that you prefer the new, standard Java class whenever possible.
*
* <p>See the Guava User Guide article on <a
* href="https://github.com/google/guava/wiki/UsingAndAvoidingNullExplained#optional">using {@code
* Optional}</a>.
*
* @param <T> the type of instance that can be contained. {@code Optional} is naturally covariant on
* this type, so it is safe to cast an {@code Optional<T>} to {@code Optional<S>} for any
* supertype {@code S} of {@code T}.
* @author Kurt Alfred Kluever
* @author Kevin Bourrillion
* @since 10.0
*/
@GwtCompatible(serializable = true)
public abstract class Optional<T> implements Serializable {
Returns an Optional
instance with no contained reference. Comparison to java.util.Optional
: this method is equivalent to Java 8's Optional.empty
.
/**
* Returns an {@code Optional} instance with no contained reference.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is equivalent to Java 8's
* {@code Optional.empty}.
*/
public static <T> Optional<T> absent() {
return Absent.withType();
}
Returns an Optional
instance containing the given non-null reference. To have
null
treated as absent
, use fromNullable
instead. Comparison to java.util.Optional
: no differences.
Throws: - NullPointerException – if
reference
is null
/**
* Returns an {@code Optional} instance containing the given non-null reference. To have {@code
* null} treated as {@link #absent}, use {@link #fromNullable} instead.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> no differences.
*
* @throws NullPointerException if {@code reference} is null
*/
public static <T> Optional<T> of(T reference) {
return new Present<T>(checkNotNull(reference));
}
If nullableReference
is non-null, returns an Optional
instance containing that reference; otherwise returns absent
. Comparison to java.util.Optional
: this method is equivalent to Java 8's Optional.ofNullable
.
/**
* If {@code nullableReference} is non-null, returns an {@code Optional} instance containing that
* reference; otherwise returns {@link Optional#absent}.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is equivalent to Java 8's
* {@code Optional.ofNullable}.
*/
public static <T> Optional<T> fromNullable(@Nullable T nullableReference) {
return (nullableReference == null) ? Optional.<T>absent() : new Present<T>(nullableReference);
}
Returns the equivalent com.google.common.base.Optional
value to the given
java.util.Optional
, or null
if the argument is null. Since: 21.0
/**
* Returns the equivalent {@code com.google.common.base.Optional} value to the given {@code
* java.util.Optional}, or {@code null} if the argument is null.
*
* @since 21.0
*/
public static <T> @Nullable Optional<T> fromJavaUtil(
java.util.@Nullable Optional<T> javaUtilOptional) {
return (javaUtilOptional == null) ? null : fromNullable(javaUtilOptional.orElse(null));
}
Returns the equivalent java.util.Optional
value to the given
com.google.common.base.Optional
, or null
if the argument is null. If googleOptional
is known to be non-null, use googleOptional.toJavaUtil()
instead.
Unfortunately, the method reference Optional::toJavaUtil
will not work, because it could refer to either the static or instance version of this method. Write out the lambda expression o -> Optional.toJavaUtil(o)
instead.
Since: 21.0
/**
* Returns the equivalent {@code java.util.Optional} value to the given {@code
* com.google.common.base.Optional}, or {@code null} if the argument is null.
*
* <p>If {@code googleOptional} is known to be non-null, use {@code googleOptional.toJavaUtil()}
* instead.
*
* <p>Unfortunately, the method reference {@code Optional::toJavaUtil} will not work, because it
* could refer to either the static or instance version of this method. Write out the lambda
* expression {@code o -> Optional.toJavaUtil(o)} instead.
*
* @since 21.0
*/
public static <T> java.util.@Nullable Optional<T> toJavaUtil(
@Nullable Optional<T> googleOptional) {
return googleOptional == null ? null : googleOptional.toJavaUtil();
}
Returns the equivalent java.util.Optional
value to this optional. Unfortunately, the method reference Optional::toJavaUtil
will not work, because it could refer to either the static or instance version of this method. Write out the lambda expression o -> o.toJavaUtil()
instead.
Since: 21.0
/**
* Returns the equivalent {@code java.util.Optional} value to this optional.
*
* <p>Unfortunately, the method reference {@code Optional::toJavaUtil} will not work, because it
* could refer to either the static or instance version of this method. Write out the lambda
* expression {@code o -> o.toJavaUtil()} instead.
*
* @since 21.0
*/
public java.util.Optional<T> toJavaUtil() {
return java.util.Optional.ofNullable(orNull());
}
Optional() {}
Returns true
if this holder contains a (non-null) instance. Comparison to java.util.Optional
: no differences.
/**
* Returns {@code true} if this holder contains a (non-null) instance.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> no differences.
*/
public abstract boolean isPresent();
Returns the contained instance, which must be present. If the instance might be absent, use or(Object)
or orNull
instead. Comparison to java.util.Optional
: when the value is absent, this method throws IllegalStateException
, whereas the Java 8 counterpart throws NoSuchElementException
.
Throws: - IllegalStateException – if the instance is absent (
isPresent
returns
false
); depending on this specific exception type (over the more general RuntimeException
) is discouraged
/**
* Returns the contained instance, which must be present. If the instance might be absent, use
* {@link #or(Object)} or {@link #orNull} instead.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> when the value is absent, this method
* throws {@link IllegalStateException}, whereas the Java 8 counterpart throws {@link
* java.util.NoSuchElementException NoSuchElementException}.
*
* @throws IllegalStateException if the instance is absent ({@link #isPresent} returns {@code
* false}); depending on this <i>specific</i> exception type (over the more general {@link
* RuntimeException}) is discouraged
*/
public abstract T get();
Returns the contained instance if it is present; defaultValue
otherwise. If no default value should be required because the instance is known to be present, use get()
instead. For a default value of null
, use orNull
. Note about generics: The signature public T or(T defaultValue)
is overly restrictive. However, the ideal signature, public <S super T> S or(S)
, is not legal Java. As a result, some sensible operations involving subtypes are compile errors:
Optional<Integer> optionalInt = getSomeOptionalInt();
Number value = optionalInt.or(0.5); // error
FluentIterable<? extends Number> numbers = getSomeNumbers();
Optional<? extends Number> first = numbers.first();
Number value = first.or(0.5); // error
As a workaround, it is always safe to cast an Optional<? extends T>
to
Optional<T>
. Casting either of the above example Optional
instances to
Optional<Number>
(where Number
is the desired output type) solves the problem:
Optional<Number> optionalInt = (Optional) getSomeOptionalInt();
Number value = optionalInt.or(0.5); // fine
FluentIterable<? extends Number> numbers = getSomeNumbers();
Optional<Number> first = (Optional) numbers.first();
Number value = first.or(0.5); // fine
Comparison to java.util.Optional
: this method is similar to Java 8's
Optional.orElse
, but will not accept null
as a defaultValue
(orNull
must be used instead). As a result, the value returned by this method is guaranteed non-null, which is not the case for the java.util
equivalent.
/**
* Returns the contained instance if it is present; {@code defaultValue} otherwise. If no default
* value should be required because the instance is known to be present, use {@link #get()}
* instead. For a default value of {@code null}, use {@link #orNull}.
*
* <p>Note about generics: The signature {@code public T or(T defaultValue)} is overly
* restrictive. However, the ideal signature, {@code public <S super T> S or(S)}, is not legal
* Java. As a result, some sensible operations involving subtypes are compile errors:
*
* <pre>{@code
* Optional<Integer> optionalInt = getSomeOptionalInt();
* Number value = optionalInt.or(0.5); // error
*
* FluentIterable<? extends Number> numbers = getSomeNumbers();
* Optional<? extends Number> first = numbers.first();
* Number value = first.or(0.5); // error
* }</pre>
*
* <p>As a workaround, it is always safe to cast an {@code Optional<? extends T>} to {@code
* Optional<T>}. Casting either of the above example {@code Optional} instances to {@code
* Optional<Number>} (where {@code Number} is the desired output type) solves the problem:
*
* <pre>{@code
* Optional<Number> optionalInt = (Optional) getSomeOptionalInt();
* Number value = optionalInt.or(0.5); // fine
*
* FluentIterable<? extends Number> numbers = getSomeNumbers();
* Optional<Number> first = (Optional) numbers.first();
* Number value = first.or(0.5); // fine
* }</pre>
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is similar to Java 8's {@code
* Optional.orElse}, but will not accept {@code null} as a {@code defaultValue} ({@link #orNull}
* must be used instead). As a result, the value returned by this method is guaranteed non-null,
* which is not the case for the {@code java.util} equivalent.
*/
public abstract T or(T defaultValue);
Returns this Optional
if it has a value present; secondChoice
otherwise. Comparison to java.util.Optional
: this method has no equivalent in Java 8's Optional
class; write thisOptional.isPresent() ? thisOptional : secondChoice
instead.
/**
* Returns this {@code Optional} if it has a value present; {@code secondChoice} otherwise.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this method has no equivalent in Java 8's
* {@code Optional} class; write {@code thisOptional.isPresent() ? thisOptional : secondChoice}
* instead.
*/
public abstract Optional<T> or(Optional<? extends T> secondChoice);
Returns the contained instance if it is present; supplier.get()
otherwise. Comparison to java.util.Optional
: this method is similar to Java 8's
Optional.orElseGet
, except when supplier
returns null
. In this case this method throws an exception, whereas the Java 8 method returns the null
to the caller.
Throws: - NullPointerException – if this optional's value is absent and the supplier returns
null
/**
* Returns the contained instance if it is present; {@code supplier.get()} otherwise.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is similar to Java 8's {@code
* Optional.orElseGet}, except when {@code supplier} returns {@code null}. In this case this
* method throws an exception, whereas the Java 8 method returns the {@code null} to the caller.
*
* @throws NullPointerException if this optional's value is absent and the supplier returns {@code
* null}
*/
@Beta
public abstract T or(Supplier<? extends T> supplier);
Returns the contained instance if it is present; null
otherwise. If the instance is known to be present, use get()
instead. Comparison to java.util.Optional
: this method is equivalent to Java 8's Optional.orElse(null)
.
/**
* Returns the contained instance if it is present; {@code null} otherwise. If the instance is
* known to be present, use {@link #get()} instead.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is equivalent to Java 8's
* {@code Optional.orElse(null)}.
*/
public abstract @Nullable T orNull();
Returns an immutable singleton Set
whose only element is the contained instance if it is present; an empty immutable Set
otherwise. Comparison to java.util.Optional
: this method has no equivalent in Java 8's Optional
class. However, this common usage:
for (Foo foo : possibleFoo.asSet()) {
doSomethingWith(foo);
}
... can be replaced with:
possibleFoo.ifPresent(foo -> doSomethingWith(foo));
Since: 11.0
/**
* Returns an immutable singleton {@link Set} whose only element is the contained instance if it
* is present; an empty immutable {@link Set} otherwise.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this method has no equivalent in Java 8's
* {@code Optional} class. However, this common usage:
*
* <pre>{@code
* for (Foo foo : possibleFoo.asSet()) {
* doSomethingWith(foo);
* }
* }</pre>
*
* ... can be replaced with:
*
* <pre>{@code
* possibleFoo.ifPresent(foo -> doSomethingWith(foo));
* }</pre>
*
* @since 11.0
*/
public abstract Set<T> asSet();
If the instance is present, it is transformed with the given Function
; otherwise, absent
is returned. Comparison to java.util.Optional
: this method is similar to Java 8's
Optional.map
, except when function
returns null
. In this case this method throws an exception, whereas the Java 8 method returns Optional.absent()
.
Throws: - NullPointerException – if the function returns
null
Since: 12.0
/**
* If the instance is present, it is transformed with the given {@link Function}; otherwise,
* {@link Optional#absent} is returned.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this method is similar to Java 8's {@code
* Optional.map}, except when {@code function} returns {@code null}. In this case this method
* throws an exception, whereas the Java 8 method returns {@code Optional.absent()}.
*
* @throws NullPointerException if the function returns {@code null}
* @since 12.0
*/
public abstract <V> Optional<V> transform(Function<? super T, V> function);
Returns true
if object
is an Optional
instance, and either the contained references are equal to each other or both are absent. Note that Optional
instances of differing parameterized types can be equal. Comparison to java.util.Optional
: no differences.
/**
* Returns {@code true} if {@code object} is an {@code Optional} instance, and either the
* contained references are {@linkplain Object#equals equal} to each other or both are absent.
* Note that {@code Optional} instances of differing parameterized types can be equal.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> no differences.
*/
@Override
public abstract boolean equals(@Nullable Object object);
Returns a hash code for this instance.
Comparison to java.util.Optional
: this class leaves the specific choice of
hash code unspecified, unlike the Java 8 equivalent.
/**
* Returns a hash code for this instance.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this class leaves the specific choice of
* hash code unspecified, unlike the Java 8 equivalent.
*/
@Override
public abstract int hashCode();
Returns a string representation for this instance.
Comparison to java.util.Optional
: this class leaves the specific string
representation unspecified, unlike the Java 8 equivalent.
/**
* Returns a string representation for this instance.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this class leaves the specific string
* representation unspecified, unlike the Java 8 equivalent.
*/
@Override
public abstract String toString();
Returns the value of each present instance from the supplied optionals
, in order, skipping over occurrences of absent
. Iterators are unmodifiable and are evaluated lazily. Comparison to java.util.Optional
: this method has no equivalent in Java 8's Optional
class; use
optionals.stream().filter(Optional::isPresent).map(Optional::get)
instead.
Since: 11.0 (generics widened in 13.0)
/**
* Returns the value of each present instance from the supplied {@code optionals}, in order,
* skipping over occurrences of {@link Optional#absent}. Iterators are unmodifiable and are
* evaluated lazily.
*
* <p><b>Comparison to {@code java.util.Optional}:</b> this method has no equivalent in Java 8's
* {@code Optional} class; use {@code
* optionals.stream().filter(Optional::isPresent).map(Optional::get)} instead.
*
* @since 11.0 (generics widened in 13.0)
*/
@Beta
public static <T> Iterable<T> presentInstances(
final Iterable<? extends Optional<? extends T>> optionals) {
checkNotNull(optionals);
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return new AbstractIterator<T>() {
private final Iterator<? extends Optional<? extends T>> iterator =
checkNotNull(optionals.iterator());
@Override
protected T computeNext() {
while (iterator.hasNext()) {
Optional<? extends T> optional = iterator.next();
if (optional.isPresent()) {
return optional.get();
}
}
return endOfData();
}
};
}
};
}
private static final long serialVersionUID = 0;
}