From 980a2d9e97af8a77929082ac1bb5c2cc05bf5a42 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sun, 19 Nov 2017 14:36:19 +0300 Subject: [PATCH] Add Optional implementation --- .../teavm/classlib/java/util/TOptional.java | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 classlib/src/main/java/org/teavm/classlib/java/util/TOptional.java diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/TOptional.java b/classlib/src/main/java/org/teavm/classlib/java/util/TOptional.java new file mode 100644 index 000000000..b7661aa64 --- /dev/null +++ b/classlib/src/main/java/org/teavm/classlib/java/util/TOptional.java @@ -0,0 +1,115 @@ +/* + * Copyright 2017 Alexey Andreev. + * + * 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 org.teavm.classlib.java.util; + +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; + +public final class TOptional { + private static TOptional emptyInstance; + private final T value; + + private TOptional(T value) { + this.value = value; + } + + @SuppressWarnings("unchecked") + public static TOptional empty() { + if (emptyInstance == null) { + emptyInstance = new TOptional<>(null); + } + return (TOptional) emptyInstance; + } + + public static TOptional of(T value) { + return new TOptional<>(Objects.requireNonNull(value)); + } + + public static TOptional ofNullable(T value) { + return value != null ? of(value) : empty(); + } + + public T get() { + if (value == null) { + throw new TNoSuchElementException(); + } + return value; + } + + public boolean isPresent() { + return value != null; + } + + public void ifPresent(Consumer consumer) { + if (value != null) { + consumer.accept(value); + } + } + + public TOptional filter(Predicate predicate) { + return value == null || predicate.test(value) ? this : empty(); + } + + @SuppressWarnings("unchecked") + public TOptional map(Function mapper) { + return value != null ? ofNullable(mapper.apply(value)) : (TOptional) this; + } + + @SuppressWarnings("unchecked") + public TOptional flatMap(Function> mapper) { + return value != null ? mapper.apply(value) : (TOptional) this; + } + + public T orElse(T other) { + return value != null ? value : other; + } + + public T orElseGet(Supplier other) { + return value != null ? value : other.get(); + } + + public T orElseThrow(Supplier exceptionSupplier) throws X { + if (value == null) { + throw exceptionSupplier.get(); + } + return value; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TOptional)) { + return false; + } + + return Objects.equals(((TOptional) obj).value, value); + } + + @Override + public int hashCode() { + return value != null ? value.hashCode() : 0; + } + + @Override + public String toString() { + return value != null ? "Optional.of(" + value + ")" : "Optional.empty()"; + } +}