/* * Copyright 2015 Google Inc. * * 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 java.util; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import static javaemul.internal.InternalPreconditions.checkCriticalElement; import static javaemul.internal.InternalPreconditions.checkCriticalNotNull; import static javaemul.internal.InternalPreconditions.checkNotNull; /** * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html"> * the official Java API doc</a> for details. * * @param <T> type of the wrapped reference */ public final class Optional<T> { @SuppressWarnings("unchecked") public static <T> Optional<T> empty() { return (Optional<T>) EMPTY; } public static <T> Optional<T> of(T value) { return new Optional<>(checkCriticalNotNull(value)); } public static <T> Optional<T> ofNullable(T value) { return value == null ? empty() : of(value); } private static final Optional<?> EMPTY = new Optional<>(null); private final T ref; private Optional(T ref) { this.ref = ref; } public boolean isPresent() { return ref != null; } public T get() { checkCriticalElement(isPresent()); return ref; } public void ifPresent(Consumer<? super T> consumer) { if (isPresent()) { consumer.accept(ref); } } public Optional<T> filter(Predicate<? super T> predicate) { checkNotNull(predicate); if (!isPresent() || predicate.test(ref)) { return this; } return empty(); } public <U> Optional<U> map(Function<? super T, ? extends U> mapper) { checkNotNull(mapper); if (isPresent()) { return ofNullable(mapper.apply(ref)); } return empty(); } public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) { checkNotNull(mapper); if (isPresent()) { return checkNotNull(mapper.apply(ref)); } return empty(); } public T orElse(T other) { return isPresent() ? ref : other; } public T orElseGet(Supplier<? extends T> other) { return isPresent() ? ref : other.get(); } public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X { if (isPresent()) { return ref; } throw exceptionSupplier.get(); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof Optional)) { return false; } Optional<?> other = (Optional<?>) obj; return Objects.equals(ref, other.ref); } @Override public int hashCode() { return Objects.hashCode(ref); } @Override public String toString() { return isPresent() ? "Optional.of(" + String.valueOf(ref) + ")" : "Optional.empty()"; } }