All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.landawn.abacus.util.u Maven / Gradle / Ivy

Go to download

A general programming library in Java/Android. It's easy to learn and simple to use with concise and powerful APIs.

There is a newer version: 5.3.16
Show newest version
/*
 * Copyright (c) 2019, Haiyang Li.
 *
 * 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.landawn.abacus.util;

import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.function.Supplier;

import com.landawn.abacus.annotation.SuppressFBWarnings;
import com.landawn.abacus.util.stream.ByteStream;
import com.landawn.abacus.util.stream.CharStream;
import com.landawn.abacus.util.stream.DoubleStream;
import com.landawn.abacus.util.stream.FloatStream;
import com.landawn.abacus.util.stream.IntStream;
import com.landawn.abacus.util.stream.LongStream;
import com.landawn.abacus.util.stream.ShortStream;
import com.landawn.abacus.util.stream.Stream;

public class u {

    private u() {
        // utility class
    }

    /**
     * The Class Optional.
     *
     * @param 
     */
    @com.landawn.abacus.annotation.Immutable
    public static final class Optional implements Immutable {

        /** Presents {@code Boolean.TRUE}. */
        public static final Optional TRUE = new Optional<>(Boolean.TRUE);

        /** Presents {@code Boolean.FALSE}. */
        public static final Optional FALSE = new Optional<>(Boolean.FALSE);

        private static final Optional EMPTY_STRING = new Optional<>(N.EMPTY_STRING);

        /** The Constant EMPTY. */
        private static final Optional EMPTY = new Optional<>();

        /** The value. */
        private final T value;

        /**
         * Instantiates a new optional.
         */
        private Optional() {
            this.value = null;
        }

        /**
         * Instantiates a new optional.
         *
         * @param value
         */
        private Optional(T value) {
            this.value = N.checkArgNotNull(value);
        }

        /**
         *
         * @param 
         * @return
         */
        public static  Optional empty() {
            return (Optional) EMPTY;
        }

        public static Optional of(final String value) {
            N.checkArgNotNull(value);

            if (value.length() == 0) {
                return EMPTY_STRING;
            }

            return new Optional<>(value);
        }

        /**
         *
         * @param 
         * @param value
         * @return
         */
        public static  Optional of(final T value) {
            return new Optional<>(value);
        }

        public static Optional ofNullable(final String value) {
            if (value == null) {
                return empty();
            } else if (value.length() == 0) {
                return EMPTY_STRING;
            }

            return new Optional<>(value);
        }

        /**
         *
         * @param 
         * @param value
         * @return
         */
        public static  Optional ofNullable(T value) {
            if (value == null) {
                return empty();
            }

            return new Optional<>(value);
        }

        /**
         *
         * @param 
         * @param op
         * @return
         */
        public static  Optional from(java.util.Optional op) {
            if (op.isPresent()) {
                return of(op.get());
            } else {
                return empty();
            }
        }

        /**
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public T get() throws NoSuchElementException {
            return orElseThrow();
        }

        /**
         * Checks if is present.
         *
         * @return true, if is present
         */
        public boolean isPresent() {
            return value != null;
        }

        /**
         * Checks if is empty.
         *
         * @return true, if is empty
         */
        public boolean isEmpty() {
            return value == null;
        }

        /**
         *
         * @param 
         * @param action
         * @return itself
         * @throws E the e
         */
        public  Optional ifPresent(final Throwables.Consumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isPresent()) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If present or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return itself
         * @throws E the e
         * @throws E2 the e2
         */
        public  Optional ifPresentOrElse(final Throwables.Consumer action,
                final Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isPresent()) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  Optional filter(final Throwables.Predicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isPresent() && predicate.test(value)) {
                return this;
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable map(final Throwables.Function mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return Nullable. of(mapper.apply(value));
            } else {
                return Nullable. empty();
            }
        }

        /**
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Optional mapToNonNull(final Throwables.Function mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return Optional. of(mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         * Map to boolean.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalBoolean mapToBoolean(final Throwables.ToBooleanFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalBoolean.of(mapper.applyAsBoolean(value));
            } else {
                return OptionalBoolean.empty();
            }
        }

        /**
         * Map to char.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalChar mapToChar(final Throwables.ToCharFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalChar.of(mapper.applyAsChar(value));
            } else {
                return OptionalChar.empty();
            }
        }

        /**
         * Map to byte.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalByte mapToByte(final Throwables.ToByteFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalByte.of(mapper.applyAsByte(value));
            } else {
                return OptionalByte.empty();
            }
        }

        /**
         * Map to short.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalShort mapToShort(final Throwables.ToShortFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalShort.of(mapper.applyAsShort(value));
            } else {
                return OptionalShort.empty();
            }
        }

        /**
         * Map to int.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt mapToInt(final Throwables.ToIntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalInt.of(mapper.applyAsInt(value));
            } else {
                return OptionalInt.empty();
            }
        }

        /**
         * Map to long.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalLong mapToLong(final Throwables.ToLongFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalLong.of(mapper.applyAsLong(value));
            } else {
                return OptionalLong.empty();
            }
        }

        /**
         * Map to float.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalFloat mapToFloat(final Throwables.ToFloatFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalFloat.of(mapper.applyAsFloat(value));
            } else {
                return OptionalFloat.empty();
            }
        }

        /**
         * Map to double.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalDouble mapToDouble(final Throwables.ToDoubleFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalDouble.of(mapper.applyAsDouble(value));
            } else {
                return OptionalDouble.empty();
            }
        }

        /**
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Optional flatMap(final Throwables.Function, E> mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        public boolean contains(final T element) {
            return isPresent() && N.equals(this.value, element);
        }

        /**
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  Optional or(final Throwables.Supplier, E> supplier) throws E {
            N.checkArgNotNull(supplier, "supplier");

            if (isPresent()) {
                return this;
            } else {
                return Objects.requireNonNull(supplier.get());
            }
        }

        /**
         *
         * @return
         * @deprecated using {@link #orElseNull()}
         */
        @Deprecated
        public T orNull() {
            return isPresent() ? value : null;
        }

        /**
         *
         * @return
         */
        public T orElseNull() {
            return isPresent() ? value : null;
        }

        /**
         *
         * @param other
         * @return
         */
        public T orElse(T other) {
            return isPresent() ? value : other;
        }

        /**
         * Or else get.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  T orElseGet(final Throwables.Supplier other) throws E {
            if (isPresent()) {
                return value;
            } else {
                return other.get();
            }
        }

        //    public T orElseNull() {
        //        return isPresent() ? value : null;
        //    }

        /**
         * Or else throw.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public T orElseThrow() throws NoSuchElementException {
            if (isPresent()) {
                return value;
            } else {
                throw new NoSuchElementException("No value is present");
            }
        }

        /**
         * Or else throw.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  T orElseThrow(final Supplier exceptionSupplier) throws X {
            if (isPresent()) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         *
         * @return
         */
        public Stream stream() {
            if (isPresent()) {
                return Stream.of(value);
            } else {
                return Stream. empty();
            }
        }

        /**
         *
         * @return
         */
        public List toList() {
            if (isPresent()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         *
         * @return
         */
        public Set toSet() {
            if (isPresent()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To immutable list.
         *
         * @return
         */
        public ImmutableList toImmutableList() {
            if (isPresent()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList. empty();
            }
        }

        /**
         * To immutable set.
         *
         * @return
         */
        public ImmutableSet toImmutableSet() {
            if (isPresent()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet. empty();
            }
        }

        /**
         *
         * @return
         */
        public java.util.Optional __() {
            if (isPresent()) {
                return java.util.Optional.of(value);
            } else {
                return java.util.Optional.empty();
            }
        }

        /**
         *
         * @param obj
         * @return
         */
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof Optional) {
                final Optional other = (Optional) obj;

                return N.equals(value, other.value);
            }

            return false;
        }

        /**
         *
         * @return
         */
        @Override
        public int hashCode() {
            return N.hashCode(isPresent()) * 31 + N.hashCode(value);
        }

        /**
         *
         * @return
         */
        @Override
        public String toString() {
            if (isPresent()) {
                return String.format("Optional[%s]", N.toString(value));
            }

            return "Optional.empty";
        }
    }

    /**
     * The Class OptionalBoolean.
     */
    @com.landawn.abacus.annotation.Immutable
    public static final class OptionalBoolean implements Comparable, Immutable {

        /** Presents {@code true}. */
        public static final OptionalBoolean TRUE = new OptionalBoolean(true);

        /** Presents {@code true}. */
        public static final OptionalBoolean FALSE = new OptionalBoolean(false);

        /** The Constant EMPTY. */
        private static final OptionalBoolean EMPTY = new OptionalBoolean();

        /** The value. */
        private final boolean value;

        /** The is present. */
        private final boolean isPresent;

        /**
         * Instantiates a new optional boolean.
         */
        private OptionalBoolean() {
            this.value = false;
            this.isPresent = false;
        }

        /**
         * Instantiates a new optional boolean.
         *
         * @param value
         */
        private OptionalBoolean(boolean value) {
            this.value = value;
            this.isPresent = true;
        }

        /**
         *
         * @return
         */
        public static OptionalBoolean empty() {
            return EMPTY;
        }

        /**
         *
         * @param value
         * @return
         */
        public static OptionalBoolean of(boolean value) {
            return value ? TRUE : FALSE;
        }

        /**
         *
         * @param val
         * @return
         */
        public static OptionalBoolean ofNullable(Boolean val) {
            if (val == null) {
                return empty();
            } else {
                return of(val);
            }
        }

        /**
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public boolean get() throws NoSuchElementException {
            return orElseThrow();
        }

        public boolean isPresent() {
            return isPresent;
        }

        public boolean isEmpty() {
            return !isPresent;
        }

        /**
         *
         * @param 
         * @param action
         * @return
         * @throws E the e
         */
        public  OptionalBoolean ifPresent(final Throwables.BooleanConsumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isPresent) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If present or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return
         * @throws E the e
         * @throws E2 the e2
         */
        public  OptionalBoolean ifPresentOrElse(final Throwables.BooleanConsumer action,
                Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isPresent) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  OptionalBoolean filter(final Throwables.BooleanPredicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isPresent && predicate.test(value)) {
                return this;
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalBoolean map(final Throwables.BooleanUnaryOperator mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalBoolean.of(mapper.applyAsBoolean(value));
            } else {
                return empty();
            }
        }

        /**
         * Map to obj.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable mapToObj(final Throwables.BooleanFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Nullable.of(mapper.apply(value));
            } else {
                return Nullable. empty();
            }
        }

        public  Optional mapToNonNull(final Throwables.BooleanFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Optional.of(mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalBoolean flatMap(final Throwables.BooleanFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  OptionalBoolean or(final Throwables.Supplier supplier) throws E {
            if (isPresent) {
                return this;
            } else {
                return Objects.requireNonNull(supplier.get());
            }
        }

        /**
         *
         * @return
         * @deprecated use {@link #orElse(false)}
         */
        @Deprecated
        public boolean orFalse() {
            return isPresent ? value : false;
        }

        //    public boolean orElseFalse() {
        //        return isPresent ? value : false;
        //    }

        /**
         *
         * @return
         * @deprecated use {@link #orElse(true)}
         */
        @Deprecated
        public boolean orTrue() {
            return isPresent ? value : true;
        }

        //    public boolean orElseTrue() {
        //        return isPresent ? value : true;
        //    }

        /**
         *
         * @param other
         * @return
         */
        public boolean orElse(boolean other) {
            return isPresent ? value : other;
        }

        /**
         * Or else get.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  boolean orElseGet(final Throwables.BooleanSupplier other) throws E {
            N.checkArgNotNull(other, "other");

            if (isPresent) {
                return value;
            } else {
                return other.getAsBoolean();
            }
        }

        /**
         * Or else throw.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public boolean orElseThrow() throws NoSuchElementException {
            if (isPresent) {
                return value;
            } else {
                throw new NoSuchElementException("No value present");
            }
        }

        /**
         * Or else throw.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  boolean orElseThrow(final Supplier exceptionSupplier) throws X {
            N.checkArgNotNull(exceptionSupplier, "exceptionSupplier");

            if (isPresent) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         *
         * @return
         */
        public Stream stream() {
            if (isPresent) {
                return Stream.of(value);
            } else {
                return Stream.empty();
            }
        }

        /**
         *
         * @return
         */
        public List toList() {
            if (isPresent()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         *
         * @return
         */
        public Set toSet() {
            if (isPresent()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To immutable list.
         *
         * @return
         */
        public ImmutableList toImmutableList() {
            if (isPresent()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList. empty();
            }
        }

        /**
         * To immutable set.
         *
         * @return
         */
        public ImmutableSet toImmutableSet() {
            if (isPresent()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet. empty();
            }
        }

        /**
         *
         * @return
         */
        public Optional boxed() {
            if (isPresent) {
                return Optional.of(value);
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param optional
         * @return
         */
        @Override
        public int compareTo(final OptionalBoolean optional) {
            if (optional == null || !optional.isPresent) {
                return isPresent ? 1 : 0;
            }

            if (!isPresent) {
                return -1;
            }

            return Boolean.compare(this.get(), optional.get());
        }

        /**
         *
         * @param obj
         * @return
         */
        @SuppressFBWarnings
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof OptionalBoolean other) {
                return (isPresent && other.isPresent) ? value == other.value : isPresent == other.isPresent;
            }

            return false;
        }

        /**
         *
         * @return
         */
        @Override
        public int hashCode() {
            return N.hashCode(isPresent) * 31 + N.hashCode(value);
        }

        /**
         *
         * @return
         */
        @Override
        public String toString() {
            if (isPresent) {
                return String.format("OptionalBoolean[%s]", value);
            }

            return "OptionalBoolean.empty";
        }
    }

    /**
     * The Class OptionalChar.
     */
    @com.landawn.abacus.annotation.Immutable
    public static final class OptionalChar implements Comparable, Immutable {

        /** The Constant EMPTY. */
        private static final OptionalChar EMPTY = new OptionalChar();

        /** The Constant MIN_CACHED_VALUE. */
        private static final char MIN_CACHED_VALUE = 0;

        /** The Constant MAX_CACHED_VALUE. */
        private static final char MAX_CACHED_VALUE = 128;

        /** The Constant cached. */
        private static final OptionalChar[] cached = new OptionalChar[MAX_CACHED_VALUE - MIN_CACHED_VALUE + 1];

        static {
            for (int i = 0; i < cached.length; i++) {
                cached[i] = new OptionalChar((char) (i + MIN_CACHED_VALUE));
            }
        }

        /** The value. */
        private final char value;

        /** The is present. */
        private final boolean isPresent;

        /**
         * Instantiates a new optional char.
         */
        private OptionalChar() {
            this.value = 0;
            this.isPresent = false;
        }

        /**
         * Instantiates a new optional char.
         *
         * @param value
         */
        private OptionalChar(char value) {
            this.value = value;
            this.isPresent = true;
        }

        /**
         *
         * @return
         */
        public static OptionalChar empty() {
            return EMPTY;
        }

        /**
         *
         * @param value
         * @return
         */
        public static OptionalChar of(char value) {
            return value >= MIN_CACHED_VALUE && value <= MAX_CACHED_VALUE ? cached[value - MIN_CACHED_VALUE] : new OptionalChar(value);
        }

        /**
         *
         * @param val
         * @return
         */
        public static OptionalChar ofNullable(Character val) {
            if (val == null) {
                return empty();
            } else {
                return of(val);
            }
        }

        /**
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public char get() throws NoSuchElementException {
            return orElseThrow();
        }

        public boolean isPresent() {
            return isPresent;
        }

        public boolean isEmpty() {
            return !isPresent;
        }

        /**
         *
         * @param 
         * @param action
         * @return
         * @throws E the e
         */
        public  OptionalChar ifPresent(final Throwables.CharConsumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isPresent()) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If present or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return
         * @throws E the e
         * @throws E2 the e2
         */
        public  OptionalChar ifPresentOrElse(final Throwables.CharConsumer action,
                final Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isPresent()) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  OptionalChar filter(final Throwables.CharPredicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isPresent() && predicate.test(value)) {
                return this;
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalChar map(final Throwables.CharUnaryOperator mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalChar.of(mapper.applyAsChar(value));
            } else {
                return empty();
            }
        }

        /**
         * Map to int.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt mapToInt(final Throwables.ToIntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalInt.of(mapper.applyAsInt(value));
            } else {
                return OptionalInt.empty();
            }
        }

        /**
         * Map to obj.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable mapToObj(final Throwables.CharFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return Nullable.of(mapper.apply(value));
            } else {
                return Nullable. empty();
            }
        }

        public  Optional mapToNonNull(final Throwables.CharFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Optional.of(mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalChar flatMap(final Throwables.CharFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  OptionalChar or(final Throwables.Supplier supplier) throws E {
            if (isPresent()) {
                return this;
            } else {
                return Objects.requireNonNull(supplier.get());
            }
        }

        /**
         *
         * @return
         * @deprecated use {@link #orElseZero()}
         */
        @Deprecated
        public char orZero() {
            return isPresent() ? value : 0;
        }

        public char orElseZero() {
            return isPresent() ? value : 0;
        }

        /**
         *
         * @param other
         * @return
         */
        public char orElse(char other) {
            return isPresent() ? value : other;
        }

        /**
         * Or else get.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  char orElseGet(final Throwables.CharSupplier other) throws E {
            N.checkArgNotNull(other, "other");

            if (isPresent()) {
                return value;
            } else {
                return other.getAsChar();
            }
        }

        /**
         * Or else throw.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public char orElseThrow() throws NoSuchElementException {
            if (isPresent()) {
                return value;
            } else {
                throw new NoSuchElementException("No value present");
            }
        }

        /**
         * Or else throw.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  char orElseThrow(final Supplier exceptionSupplier) throws X {
            N.checkArgNotNull(exceptionSupplier, "exceptionSupplier");

            if (isPresent()) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         *
         * @return
         */
        public CharStream stream() {
            if (isPresent) {
                return CharStream.of(value);
            } else {
                return CharStream.empty();
            }
        }

        /**
         *
         * @return
         */
        public List toList() {
            if (isPresent()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         *
         * @return
         */
        public Set toSet() {
            if (isPresent()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To immutable list.
         *
         * @return
         */
        public ImmutableList toImmutableList() {
            if (isPresent()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList. empty();
            }
        }

        /**
         * To immutable set.
         *
         * @return
         */
        public ImmutableSet toImmutableSet() {
            if (isPresent()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet. empty();
            }
        }

        /**
         *
         * @return
         */
        public Optional boxed() {
            if (isPresent()) {
                return Optional.of(value);
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param optional
         * @return
         */
        @Override
        public int compareTo(final OptionalChar optional) {
            if (optional == null || !optional.isPresent()) {
                return isPresent ? 1 : 0;
            }

            if (!isPresent) {
                return -1;
            }

            return Character.compare(this.get(), optional.get());
        }

        /**
         *
         * @param obj
         * @return
         */
        @SuppressFBWarnings
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof OptionalChar other) {
                return (isPresent && other.isPresent) ? value == other.value : isPresent == other.isPresent;
            }

            return false;
        }

        /**
         *
         * @return
         */
        @Override
        public int hashCode() {
            return N.hashCode(isPresent()) * 31 + N.hashCode(value);
        }

        /**
         *
         * @return
         */
        @Override
        public String toString() {
            if (isPresent()) {
                return String.format("OptionalChar[%s]", value);
            }

            return "OptionalChar.empty";
        }
    }

    /**
     * The Class OptionalByte.
     */
    @com.landawn.abacus.annotation.Immutable
    public static final class OptionalByte implements Comparable, Immutable {

        /** The Constant EMPTY. */
        private static final OptionalByte EMPTY = new OptionalByte();

        /** The Constant MIN_CACHED_VALUE. */
        private static final byte MIN_CACHED_VALUE = Byte.MIN_VALUE;

        /** The Constant MAX_CACHED_VALUE. */
        private static final byte MAX_CACHED_VALUE = Byte.MAX_VALUE;

        /** The Constant cached. */
        private static final OptionalByte[] cached = new OptionalByte[MAX_CACHED_VALUE - MIN_CACHED_VALUE + 1];

        static {
            for (int i = 0; i < cached.length; i++) {
                cached[i] = new OptionalByte((byte) (i + MIN_CACHED_VALUE));
            }
        }

        /** The value. */
        private final byte value;

        /** The is present. */
        private final boolean isPresent;

        /**
         * Instantiates a new optional byte.
         */
        private OptionalByte() {
            this.value = 0;
            this.isPresent = false;
        }

        /**
         * Instantiates a new optional byte.
         *
         * @param value
         */
        private OptionalByte(byte value) {
            this.value = value;
            this.isPresent = true;
        }

        /**
         *
         * @return
         */
        public static OptionalByte empty() {
            return EMPTY;
        }

        /**
         *
         * @param value
         * @return
         */
        public static OptionalByte of(byte value) {
            return cached[value - MIN_CACHED_VALUE];
        }

        /**
         *
         * @param val
         * @return
         */
        public static OptionalByte ofNullable(Byte val) {
            if (val == null) {
                return empty();
            } else {
                return OptionalByte.of(val);
            }
        }

        /**
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public byte get() throws NoSuchElementException {
            return orElseThrow();
        }

        public boolean isPresent() {
            return isPresent;
        }

        public boolean isEmpty() {
            return !isPresent;
        }

        /**
         *
         * @param 
         * @param action
         * @return
         * @throws E the e
         */
        public  OptionalByte ifPresent(final Throwables.ByteConsumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isPresent) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If present or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return
         * @throws E the e
         * @throws E2 the e2
         */
        public  OptionalByte ifPresentOrElse(final Throwables.ByteConsumer action,
                final Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isPresent) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  OptionalByte filter(final Throwables.BytePredicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isPresent && predicate.test(value)) {
                return this;
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalByte map(final Throwables.ByteUnaryOperator mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalByte.of(mapper.applyAsByte(value));
            } else {
                return empty();
            }
        }

        /**
         * Map to int.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt mapToInt(final Throwables.ToIntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalInt.of(mapper.applyAsInt(value));
            } else {
                return OptionalInt.empty();
            }
        }

        /**
         * Map to obj.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable mapToObj(final Throwables.ByteFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Nullable.of(mapper.apply(value));
            } else {
                return Nullable. empty();
            }
        }

        public  Optional mapToNonNull(final Throwables.ByteFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Optional.of(mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalByte flatMap(final Throwables.ByteFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  OptionalByte or(final Throwables.Supplier supplier) throws E {
            if (isPresent) {
                return this;
            } else {
                return Objects.requireNonNull(supplier.get());
            }
        }

        /**
         *
         * @return
         * @deprecated use {@link #orElseZero()}
         */
        @Deprecated
        public byte orZero() {
            return isPresent ? value : 0;
        }

        public byte orElseZero() {
            return isPresent ? value : 0;
        }

        /**
         *
         * @param other
         * @return
         */
        public byte orElse(byte other) {
            return isPresent ? value : other;
        }

        /**
         * Or else get.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  byte orElseGet(final Throwables.ByteSupplier other) throws E {
            N.checkArgNotNull(other, "other");

            if (isPresent) {
                return value;
            } else {
                return other.getAsByte();
            }
        }

        /**
         * Or else throw.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public byte orElseThrow() throws NoSuchElementException {
            if (isPresent) {
                return value;
            } else {
                throw new NoSuchElementException("No value present");
            }
        }

        /**
         * Or else throw.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  byte orElseThrow(final Supplier exceptionSupplier) throws X {
            N.checkArgNotNull(exceptionSupplier, "exceptionSupplier");

            if (isPresent) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         *
         * @return
         */
        public ByteStream stream() {
            if (isPresent) {
                return ByteStream.of(value);
            } else {
                return ByteStream.empty();
            }
        }

        /**
         *
         * @return
         */
        public List toList() {
            if (isPresent()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         *
         * @return
         */
        public Set toSet() {
            if (isPresent()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To immutable list.
         *
         * @return
         */
        public ImmutableList toImmutableList() {
            if (isPresent()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList. empty();
            }
        }

        /**
         * To immutable set.
         *
         * @return
         */
        public ImmutableSet toImmutableSet() {
            if (isPresent()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet. empty();
            }
        }

        /**
         *
         * @return
         */
        public Optional boxed() {
            if (isPresent) {
                return Optional.of(value);
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param optional
         * @return
         */
        @Override
        public int compareTo(final OptionalByte optional) {
            if (optional == null || !optional.isPresent) {
                return isPresent ? 1 : 0;
            }

            if (!isPresent) {
                return -1;
            }

            return Byte.compare(this.get(), optional.get());
        }

        /**
         *
         * @param obj
         * @return
         */
        @SuppressFBWarnings
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof OptionalByte other) {
                return (isPresent && other.isPresent) ? value == other.value : isPresent == other.isPresent;
            }

            return false;
        }

        /**
         *
         * @return
         */
        @Override
        public int hashCode() {
            return N.hashCode(isPresent) * 31 + N.hashCode(value);
        }

        /**
         *
         * @return
         */
        @Override
        public String toString() {
            if (isPresent) {
                return String.format("OptionalByte[%s]", value);
            }

            return "OptionalByte.empty";
        }
    }

    /**
     * The Class OptionalShort.
     */
    @com.landawn.abacus.annotation.Immutable
    public static final class OptionalShort implements Comparable, Immutable {

        /** The Constant EMPTY. */
        private static final OptionalShort EMPTY = new OptionalShort();

        /** The Constant MIN_CACHED_VALUE. */
        private static final short MIN_CACHED_VALUE = -128;

        /** The Constant MAX_CACHED_VALUE. */
        private static final short MAX_CACHED_VALUE = 256;

        /** The Constant cached. */
        private static final OptionalShort[] cached = new OptionalShort[MAX_CACHED_VALUE - MIN_CACHED_VALUE + 1];

        static {
            for (int i = 0; i < cached.length; i++) {
                cached[i] = new OptionalShort((short) (i + MIN_CACHED_VALUE));
            }
        }

        /** The value. */
        private final short value;

        /** The is present. */
        private final boolean isPresent;

        /**
         * Instantiates a new optional short.
         */
        private OptionalShort() {
            this.value = 0;
            this.isPresent = false;
        }

        /**
         * Instantiates a new optional short.
         *
         * @param value
         */
        private OptionalShort(short value) {
            this.value = value;
            this.isPresent = true;
        }

        /**
         *
         * @return
         */
        public static OptionalShort empty() {
            return EMPTY;
        }

        /**
         *
         * @param value
         * @return
         */
        public static OptionalShort of(short value) {
            return value >= MIN_CACHED_VALUE && value <= MAX_CACHED_VALUE ? cached[value - MIN_CACHED_VALUE] : new OptionalShort(value);
        }

        /**
         *
         * @param val
         * @return
         */
        public static OptionalShort ofNullable(Short val) {
            if (val == null) {
                return empty();
            } else {
                return OptionalShort.of(val);
            }
        }

        /**
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public short get() throws NoSuchElementException {
            return orElseThrow();
        }

        public boolean isPresent() {
            return isPresent;
        }

        public boolean isEmpty() {
            return !isPresent;
        }

        /**
         *
         * @param 
         * @param action
         * @return
         * @throws E the e
         */
        public  OptionalShort ifPresent(final Throwables.ShortConsumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isPresent) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If present or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return
         * @throws E the e
         * @throws E2 the e2
         */
        public  OptionalShort ifPresentOrElse(final Throwables.ShortConsumer action,
                Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isPresent) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  OptionalShort filter(final Throwables.ShortPredicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isPresent && predicate.test(value)) {
                return this;
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalShort map(final Throwables.ShortUnaryOperator mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalShort.of(mapper.applyAsShort(value));
            } else {
                return empty();
            }
        }

        /**
         * Map to int.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt mapToInt(final Throwables.ToIntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalInt.of(mapper.applyAsInt(value));
            } else {
                return OptionalInt.empty();
            }
        }

        /**
         * Map to obj.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable mapToObj(final Throwables.ShortFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Nullable.of(mapper.apply(value));
            } else {
                return Nullable. empty();
            }
        }

        public  Optional mapToNonNull(final Throwables.ShortFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Optional.of(mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalShort flatMap(final Throwables.ShortFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  OptionalShort or(final Throwables.Supplier supplier) throws E {
            if (isPresent) {
                return this;
            } else {
                return Objects.requireNonNull(supplier.get());
            }
        }

        /**
         *
         * @return
         * @deprecated use {@link #orElseZero()}
         */
        @Deprecated
        public short orZero() {
            return isPresent ? value : 0;
        }

        public short orElseZero() {
            return isPresent ? value : 0;
        }

        /**
         *
         * @param other
         * @return
         */
        public short orElse(short other) {
            return isPresent ? value : other;
        }

        /**
         * Or else get.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  short orElseGet(final Throwables.ShortSupplier other) throws E {
            N.checkArgNotNull(other, "other");

            if (isPresent) {
                return value;
            } else {
                return other.getAsShort();
            }
        }

        /**
         * Or else throw.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public short orElseThrow() throws NoSuchElementException {
            if (isPresent) {
                return value;
            } else {
                throw new NoSuchElementException("No value present");
            }
        }

        /**
         * Or else throw.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  short orElseThrow(final Supplier exceptionSupplier) throws X {
            N.checkArgNotNull(exceptionSupplier, "exceptionSupplier");

            if (isPresent) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         *
         * @return
         */
        public ShortStream stream() {
            if (isPresent) {
                return ShortStream.of(value);
            } else {
                return ShortStream.empty();
            }
        }

        /**
         *
         * @return
         */
        public List toList() {
            if (isPresent()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         *
         * @return
         */
        public Set toSet() {
            if (isPresent()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To immutable list.
         *
         * @return
         */
        public ImmutableList toImmutableList() {
            if (isPresent()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList. empty();
            }
        }

        /**
         * To immutable set.
         *
         * @return
         */
        public ImmutableSet toImmutableSet() {
            if (isPresent()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet. empty();
            }
        }

        /**
         *
         * @return
         */
        public Optional boxed() {
            if (isPresent) {
                return Optional.of(value);
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param optional
         * @return
         */
        @Override
        public int compareTo(final OptionalShort optional) {
            if (optional == null || !optional.isPresent) {
                return isPresent ? 1 : 0;
            }

            if (!isPresent) {
                return -1;
            }

            return Short.compare(this.get(), optional.get());
        }

        /**
         *
         * @param obj
         * @return
         */
        @SuppressFBWarnings
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof OptionalShort other) {
                return (isPresent && other.isPresent) ? value == other.value : isPresent == other.isPresent;
            }

            return false;
        }

        /**
         *
         * @return
         */
        @Override
        public int hashCode() {
            return N.hashCode(isPresent) * 31 + N.hashCode(value);
        }

        /**
         *
         * @return
         */
        @Override
        public String toString() {
            if (isPresent) {
                return String.format("OptionalShort[%s]", value);
            }

            return "OptionalShort.empty";
        }
    }

    /**
     * The Class OptionalInt.
     */
    @com.landawn.abacus.annotation.Immutable
    public static final class OptionalInt implements Comparable, Immutable {

        /** The Constant EMPTY. */
        private static final OptionalInt EMPTY = new OptionalInt();

        /** The Constant MIN_CACHED_VALUE. */
        private static final int MIN_CACHED_VALUE = -256;

        /** The Constant MAX_CACHED_VALUE. */
        private static final int MAX_CACHED_VALUE = 1024;

        /** The Constant cached. */
        private static final OptionalInt[] cached = new OptionalInt[MAX_CACHED_VALUE - MIN_CACHED_VALUE + 1];

        static {
            for (int i = 0; i < cached.length; i++) {
                cached[i] = new OptionalInt(i + MIN_CACHED_VALUE);
            }
        }

        /** The value. */
        private final int value;

        /** The is present. */
        private final boolean isPresent;

        /**
         * Instantiates a new optional int.
         */
        private OptionalInt() {
            this.value = 0;
            this.isPresent = false;
        }

        /**
         * Instantiates a new optional int.
         *
         * @param value
         */
        private OptionalInt(int value) {
            this.value = value;
            this.isPresent = true;
        }

        /**
         *
         * @return
         */
        public static OptionalInt empty() {
            return EMPTY;
        }

        /**
         *
         * @param value
         * @return
         */
        public static OptionalInt of(int value) {
            return value >= MIN_CACHED_VALUE && value <= MAX_CACHED_VALUE ? cached[value - MIN_CACHED_VALUE] : new OptionalInt(value);
        }

        /**
         *
         * @param val
         * @return
         */
        public static OptionalInt ofNullable(Integer val) {
            if (val == null) {
                return empty();
            } else {
                return OptionalInt.of(val);
            }
        }

        /**
         *
         * @param op
         * @return
         */
        public static OptionalInt from(java.util.OptionalInt op) {
            if (op.isPresent()) {
                return of(op.getAsInt());
            } else {
                return empty();
            }
        }

        /**
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public int get() throws NoSuchElementException {
            return orElseThrow();
        }

        public boolean isPresent() {
            return isPresent;
        }

        public boolean isEmpty() {
            return !isPresent;
        }

        /**
         *
         * @param 
         * @param action
         * @return
         * @throws E the e
         */
        public  OptionalInt ifPresent(final Throwables.IntConsumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isPresent) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If present or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return
         * @throws E the e
         * @throws E2 the e2
         */
        public  OptionalInt ifPresentOrElse(final Throwables.IntConsumer action,
                final Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isPresent) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  OptionalInt filter(final Throwables.IntPredicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isPresent && predicate.test(value)) {
                return this;
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt map(final Throwables.IntUnaryOperator mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalInt.of(mapper.applyAsInt(value));
            } else {
                return empty();
            }
        }

        /**
         * Map to long.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalLong mapToLong(final Throwables.ToLongFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalLong.of(mapper.applyAsLong(value));
            } else {
                return OptionalLong.empty();
            }
        }

        /**
         * Map to float.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalFloat mapToFloat(final Throwables.ToFloatFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalFloat.of(mapper.applyAsFloat(value));
            } else {
                return OptionalFloat.empty();
            }
        }

        /**
         * Map to double.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalDouble mapToDouble(final Throwables.ToDoubleFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalDouble.of(mapper.applyAsDouble(value));
            } else {
                return OptionalDouble.empty();
            }
        }

        /**
         * Map to obj.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable mapToObj(final Throwables.IntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Nullable.of(mapper.apply(value));
            } else {
                return Nullable. empty();
            }
        }

        public  Optional mapToNonNull(final Throwables.IntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Optional.of(mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt flatMap(final Throwables.IntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  OptionalInt or(final Throwables.Supplier supplier) throws E {
            if (isPresent) {
                return this;
            } else {
                return Objects.requireNonNull(supplier.get());
            }
        }

        /**
         *
         * @return
         * @deprecated use {@link #orElseZero()}
         */
        @Deprecated
        public int orZero() {
            return isPresent ? value : 0;
        }

        public int orElseZero() {
            return isPresent ? value : 0;
        }

        /**
         *
         * @param other
         * @return
         */
        public int orElse(int other) {
            return isPresent ? value : other;
        }

        /**
         * Or else get.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  int orElseGet(final Throwables.IntSupplier other) throws E {
            N.checkArgNotNull(other, "other");

            if (isPresent) {
                return value;
            } else {
                return other.getAsInt();
            }
        }

        /**
         * Or else throw.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public int orElseThrow() throws NoSuchElementException {
            if (isPresent) {
                return value;
            } else {
                throw new NoSuchElementException("No value present");
            }
        }

        /**
         * Or else throw.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  int orElseThrow(final Supplier exceptionSupplier) throws X {
            N.checkArgNotNull(exceptionSupplier, "exceptionSupplier");

            if (isPresent) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         *
         * @return
         */
        public IntStream stream() {
            if (isPresent) {
                return IntStream.of(value);
            } else {
                return IntStream.empty();
            }
        }

        /**
         *
         * @return
         */
        public List toList() {
            if (isPresent()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         *
         * @return
         */
        public Set toSet() {
            if (isPresent()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To immutable list.
         *
         * @return
         */
        public ImmutableList toImmutableList() {
            if (isPresent()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList. empty();
            }
        }

        /**
         * To immutable set.
         *
         * @return
         */
        public ImmutableSet toImmutableSet() {
            if (isPresent()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet. empty();
            }
        }

        /**
         *
         * @return
         */
        public Optional boxed() {
            if (isPresent) {
                return Optional.of(value);
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @return
         */
        public java.util.OptionalInt __() {
            if (isPresent) {
                return java.util.OptionalInt.of(value);
            } else {
                return java.util.OptionalInt.empty();
            }
        }

        /**
         *
         * @param optional
         * @return
         */
        @Override
        public int compareTo(final OptionalInt optional) {
            if (optional == null || !optional.isPresent) {
                return isPresent ? 1 : 0;
            }

            if (!isPresent) {
                return -1;
            }

            return Integer.compare(this.get(), optional.get());
        }

        /**
         *
         * @param obj
         * @return
         */
        @SuppressFBWarnings
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof OptionalInt other) {
                return (isPresent && other.isPresent) ? value == other.value : isPresent == other.isPresent;
            }

            return false;
        }

        /**
         *
         * @return
         */
        @Override
        public int hashCode() {
            return N.hashCode(isPresent) * 31 + N.hashCode(value);
        }

        /**
         *
         * @return
         */
        @Override
        public String toString() {
            if (isPresent) {
                return String.format("OptionalInt[%s]", value);
            }

            return "OptionalInt.empty";
        }
    }

    /**
     * The Class OptionalLong.
     */
    @com.landawn.abacus.annotation.Immutable
    public static final class OptionalLong implements Comparable, Immutable {

        /** The Constant EMPTY. */
        private static final OptionalLong EMPTY = new OptionalLong();

        /** The Constant MIN_CACHED_VALUE. */
        private static final long MIN_CACHED_VALUE = -256;

        /** The Constant MAX_CACHED_VALUE. */
        private static final long MAX_CACHED_VALUE = 1024;

        /** The Constant cached. */
        private static final OptionalLong[] cached = new OptionalLong[(int) (MAX_CACHED_VALUE - MIN_CACHED_VALUE + 1)];

        static {
            for (int i = 0; i < cached.length; i++) {
                cached[i] = new OptionalLong(i + MIN_CACHED_VALUE);
            }
        }

        /** The value. */
        private final long value;

        /** The is present. */
        private final boolean isPresent;

        /**
         * Instantiates a new optional long.
         */
        private OptionalLong() {
            this.value = 0;
            this.isPresent = false;
        }

        /**
         * Instantiates a new optional long.
         *
         * @param value
         */
        private OptionalLong(long value) {
            this.value = value;
            this.isPresent = true;
        }

        /**
         *
         * @return
         */
        public static OptionalLong empty() {
            return EMPTY;
        }

        /**
         *
         * @param value
         * @return
         */
        public static OptionalLong of(long value) {
            return value >= MIN_CACHED_VALUE && value <= MAX_CACHED_VALUE ? cached[(int) (value - MIN_CACHED_VALUE)] : new OptionalLong(value);
        }

        /**
         *
         * @param val
         * @return
         */
        public static OptionalLong ofNullable(Long val) {
            if (val == null) {
                return empty();
            } else {
                return OptionalLong.of(val);
            }
        }

        /**
         *
         * @param op
         * @return
         */
        public static OptionalLong from(java.util.OptionalLong op) {
            if (op.isPresent()) {
                return of(op.getAsLong());
            } else {
                return empty();
            }
        }

        /**
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public long get() throws NoSuchElementException {
            return orElseThrow();
        }

        public boolean isPresent() {
            return isPresent;
        }

        public boolean isEmpty() {
            return !isPresent;
        }

        /**
         *
         * @param 
         * @param action
         * @return
         * @throws E the e
         */
        public  OptionalLong ifPresent(final Throwables.LongConsumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isPresent) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If present or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return
         * @throws E the e
         * @throws E2 the e2
         */
        public  OptionalLong ifPresentOrElse(final Throwables.LongConsumer action,
                final Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isPresent) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  OptionalLong filter(final Throwables.LongPredicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isPresent && predicate.test(value)) {
                return this;
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalLong map(final Throwables.LongUnaryOperator mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalLong.of(mapper.applyAsLong(value));
            } else {
                return empty();
            }
        }

        /**
         * Map to int.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt mapToInt(final Throwables.ToIntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalInt.of(mapper.applyAsInt(value));
            } else {
                return OptionalInt.empty();
            }
        }

        /**
         * Map to double.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalDouble mapToDouble(final Throwables.ToDoubleFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalDouble.of(mapper.applyAsDouble(value));
            } else {
                return OptionalDouble.empty();
            }
        }

        /**
         * Map to obj.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable mapToObj(final Throwables.LongFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Nullable.of(mapper.apply(value));
            } else {
                return Nullable. empty();
            }
        }

        public  Optional mapToNonNull(final Throwables.LongFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Optional.of(mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalLong flatMap(final Throwables.LongFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  OptionalLong or(final Throwables.Supplier supplier) throws E {
            if (isPresent) {
                return this;
            } else {
                return Objects.requireNonNull(supplier.get());
            }
        }

        /**
         *
         * @return
         * @deprecated use {@link #orElseZero()}
         */
        @Deprecated
        public long orZero() {
            return isPresent ? value : 0;
        }

        public long orElseZero() {
            return isPresent ? value : 0;
        }

        /**
         *
         * @param other
         * @return
         */
        public long orElse(long other) {
            return isPresent ? value : other;
        }

        /**
         * Or else get.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  long orElseGet(final Throwables.LongSupplier other) throws E {
            N.checkArgNotNull(other, "other");

            if (isPresent) {
                return value;
            } else {
                return other.getAsLong();
            }
        }

        /**
         * Or else throw.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public long orElseThrow() throws NoSuchElementException {
            if (isPresent) {
                return value;
            } else {
                throw new NoSuchElementException("No value present");
            }
        }

        /**
         * Or else throw.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  long orElseThrow(final Supplier exceptionSupplier) throws X {
            N.checkArgNotNull(exceptionSupplier, "exceptionSupplier");

            if (isPresent) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         *
         * @return
         */
        public LongStream stream() {
            if (isPresent) {
                return LongStream.of(value);
            } else {
                return LongStream.empty();
            }
        }

        /**
         *
         * @return
         */
        public List toList() {
            if (isPresent()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         *
         * @return
         */
        public Set toSet() {
            if (isPresent()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To immutable list.
         *
         * @return
         */
        public ImmutableList toImmutableList() {
            if (isPresent()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList. empty();
            }
        }

        /**
         * To immutable set.
         *
         * @return
         */
        public ImmutableSet toImmutableSet() {
            if (isPresent()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet. empty();
            }
        }

        /**
         *
         * @return
         */
        public Optional boxed() {
            if (isPresent) {
                return Optional.of(value);
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @return
         */
        public java.util.OptionalLong __() {
            if (isPresent) {
                return java.util.OptionalLong.of(value);
            } else {
                return java.util.OptionalLong.empty();
            }
        }

        /**
         *
         * @param optional
         * @return
         */
        @Override
        public int compareTo(final OptionalLong optional) {
            if (optional == null || !optional.isPresent) {
                return isPresent ? 1 : 0;
            }

            if (!isPresent) {
                return -1;
            }

            return Long.compare(this.get(), optional.get());
        }

        /**
         *
         * @param obj
         * @return
         */
        @SuppressFBWarnings
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof OptionalLong other) {
                return (isPresent && other.isPresent) ? value == other.value : isPresent == other.isPresent;
            }

            return false;
        }

        /**
         *
         * @return
         */
        @Override
        public int hashCode() {
            return N.hashCode(isPresent) * 31 + N.hashCode(value);
        }

        /**
         *
         * @return
         */
        @Override
        public String toString() {
            if (isPresent) {
                return String.format("OptionalLong[%s]", value);
            }

            return "OptionalLong.empty";
        }
    }

    /**
     * The Class OptionalFloat.
     */
    @com.landawn.abacus.annotation.Immutable
    public static final class OptionalFloat implements Comparable, Immutable {

        /** The Constant EMPTY. */
        private static final OptionalFloat EMPTY = new OptionalFloat();

        /** The value. */
        private final float value;

        /** The is present. */
        private final boolean isPresent;

        /**
         * Instantiates a new optional float.
         */
        private OptionalFloat() {
            this.value = 0;
            this.isPresent = false;
        }

        /**
         * Instantiates a new optional float.
         *
         * @param value
         */
        private OptionalFloat(float value) {
            this.value = value;
            this.isPresent = true;
        }

        /**
         *
         * @return
         */
        public static OptionalFloat empty() {
            return EMPTY;
        }

        /**
         *
         * @param value
         * @return
         */
        public static OptionalFloat of(float value) {
            return new OptionalFloat(value);
        }

        /**
         *
         * @param val
         * @return
         */
        public static OptionalFloat ofNullable(Float val) {
            if (val == null) {
                return empty();
            } else {
                return OptionalFloat.of(val);
            }
        }

        /**
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public float get() throws NoSuchElementException {
            return orElseThrow();
        }

        public boolean isPresent() {
            return isPresent;
        }

        public boolean isEmpty() {
            return !isPresent;
        }

        /**
         *
         * @param 
         * @param action
         * @return
         * @throws E the e
         */
        public  OptionalFloat ifPresent(final Throwables.FloatConsumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isPresent) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If present or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return
         * @throws E the e
         * @throws E2 the e2
         */
        public  OptionalFloat ifPresentOrElse(final Throwables.FloatConsumer action,
                Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isPresent) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  OptionalFloat filter(final Throwables.FloatPredicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isPresent && predicate.test(value)) {
                return this;
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalFloat map(final Throwables.FloatUnaryOperator mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalFloat.of(mapper.applyAsFloat(value));
            } else {
                return empty();
            }
        }

        /**
         * Map to int.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt mapToInt(final Throwables.ToIntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalInt.of(mapper.applyAsInt(value));
            } else {
                return OptionalInt.empty();
            }
        }

        /**
         * Map to double.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalDouble mapToDouble(final Throwables.ToDoubleFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalDouble.of(mapper.applyAsDouble(value));
            } else {
                return OptionalDouble.empty();
            }
        }

        /**
         * Map to obj.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable mapToObj(final Throwables.FloatFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Nullable.of(mapper.apply(value));
            } else {
                return Nullable. empty();
            }
        }

        public  Optional mapToNonNull(final Throwables.FloatFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Optional.of(mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalFloat flatMap(final Throwables.FloatFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  OptionalFloat or(final Throwables.Supplier supplier) throws E {
            if (isPresent) {
                return this;
            } else {
                return Objects.requireNonNull(supplier.get());
            }
        }

        /**
         *
         * @return
         * @deprecated use {@link #orElseZero()}
         */
        @Deprecated
        public float orZero() {
            return isPresent ? value : 0;
        }

        public float orElseZero() {
            return isPresent ? value : 0;
        }

        /**
         *
         * @param other
         * @return
         */
        public float orElse(float other) {
            return isPresent ? value : other;
        }

        /**
         * Or else get.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  float orElseGet(final Throwables.FloatSupplier other) throws E {
            N.checkArgNotNull(other, "other");

            if (isPresent) {
                return value;
            } else {
                return other.getAsFloat();
            }
        }

        /**
         * Or else throw.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public float orElseThrow() throws NoSuchElementException {
            if (isPresent) {
                return value;
            } else {
                throw new NoSuchElementException("No value present");
            }
        }

        /**
         * Or else throw.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  float orElseThrow(final Supplier exceptionSupplier) throws X {
            N.checkArgNotNull(exceptionSupplier, "exceptionSupplier");

            if (isPresent) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         *
         * @return
         */
        public FloatStream stream() {
            if (isPresent) {
                return FloatStream.of(value);
            } else {
                return FloatStream.empty();
            }
        }

        /**
         *
         * @return
         */
        public List toList() {
            if (isPresent()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         *
         * @return
         */
        public Set toSet() {
            if (isPresent()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To immutable list.
         *
         * @return
         */
        public ImmutableList toImmutableList() {
            if (isPresent()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList. empty();
            }
        }

        /**
         * To immutable set.
         *
         * @return
         */
        public ImmutableSet toImmutableSet() {
            if (isPresent()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet. empty();
            }
        }

        /**
         *
         * @return
         */
        public Optional boxed() {
            if (isPresent) {
                return Optional.of(value);
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param optional
         * @return
         */
        @Override
        public int compareTo(final OptionalFloat optional) {
            if (optional == null || !optional.isPresent) {
                return isPresent ? 1 : 0;
            }

            if (!isPresent) {
                return -1;
            }

            return Float.compare(this.get(), optional.get());
        }

        /**
         *
         * @param obj
         * @return
         */
        @SuppressFBWarnings
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof OptionalFloat other) {
                return (isPresent && other.isPresent) ? N.equals(value, other.value) : isPresent == other.isPresent;
            }

            return false;
        }

        /**
         *
         * @return
         */
        @Override
        public int hashCode() {
            return N.hashCode(isPresent) * 31 + N.hashCode(value);
        }

        /**
         *
         * @return
         */
        @Override
        public String toString() {
            if (isPresent) {
                return String.format("OptionalFloat[%s]", value);
            }

            return "OptionalFloat.empty";
        }
    }

    /**
     * The Class OptionalDouble.
     */
    @com.landawn.abacus.annotation.Immutable
    public static final class OptionalDouble implements Comparable, Immutable {

        /** The Constant EMPTY. */
        private static final OptionalDouble EMPTY = new OptionalDouble();

        /** The value. */
        private final double value;

        /** The is present. */
        private final boolean isPresent;

        /**
         * Instantiates a new optional double.
         */
        private OptionalDouble() {
            this.value = 0;
            this.isPresent = false;
        }

        /**
         * Instantiates a new optional double.
         *
         * @param value
         */
        private OptionalDouble(double value) {
            this.value = value;
            this.isPresent = true;
        }

        /**
         *
         * @return
         */
        public static OptionalDouble empty() {
            return EMPTY;
        }

        /**
         *
         * @param value
         * @return
         */
        public static OptionalDouble of(double value) {
            return new OptionalDouble(value);
        }

        /**
         *
         * @param val
         * @return
         */
        public static OptionalDouble ofNullable(Double val) {
            if (val == null) {
                return empty();
            } else {
                return OptionalDouble.of(val);
            }
        }

        /**
         *
         * @param op
         * @return
         */
        public static OptionalDouble from(java.util.OptionalDouble op) {
            if (op.isPresent()) {
                return of(op.getAsDouble());
            } else {
                return empty();
            }
        }

        /**
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public double get() throws NoSuchElementException {
            return orElseThrow();
        }

        public boolean isPresent() {
            return isPresent;
        }

        public boolean isEmpty() {
            return !isPresent;
        }

        /**
         *
         * @param 
         * @param action
         * @return
         * @throws E the e
         */
        public  OptionalDouble ifPresent(final Throwables.DoubleConsumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isPresent) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If present or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return
         * @throws E the e
         * @throws E2 the e2
         */
        public  OptionalDouble ifPresentOrElse(final Throwables.DoubleConsumer action,
                Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isPresent) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  OptionalDouble filter(final Throwables.DoublePredicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isPresent && predicate.test(value)) {
                return this;
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalDouble map(final Throwables.DoubleUnaryOperator mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalDouble.of(mapper.applyAsDouble(value));
            } else {
                return empty();
            }
        }

        /**
         * Map to int.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt mapToInt(final Throwables.ToIntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalInt.of(mapper.applyAsInt(value));
            } else {
                return OptionalInt.empty();
            }
        }

        /**
         * Map to long.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalLong mapToLong(final Throwables.ToLongFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return OptionalLong.of(mapper.applyAsLong(value));
            } else {
                return OptionalLong.empty();
            }
        }

        /**
         * Map to obj.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable mapToObj(final Throwables.DoubleFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Nullable.of(mapper.apply(value));
            } else {
                return Nullable. empty();
            }
        }

        public  Optional mapToNonNull(final Throwables.DoubleFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Optional.of(mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalDouble flatMap(final Throwables.DoubleFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  OptionalDouble or(final Throwables.Supplier supplier) throws E {
            if (isPresent) {
                return this;
            } else {
                return Objects.requireNonNull(supplier.get());
            }
        }

        /**
         *
         * @return
         * @deprecated use {@link #orElseZero()}
         */
        @Deprecated
        public double orZero() {
            return isPresent ? value : 0;
        }

        public double orElseZero() {
            return isPresent ? value : 0;
        }

        /**
         *
         * @param other
         * @return
         */
        public double orElse(double other) {
            return isPresent ? value : other;
        }

        /**
         * Or else get.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  double orElseGet(final Throwables.DoubleSupplier other) throws E {
            N.checkArgNotNull(other, "other");

            if (isPresent) {
                return value;
            } else {
                return other.getAsDouble();
            }
        }

        /**
         * Or else throw.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public double orElseThrow() throws NoSuchElementException {
            if (isPresent) {
                return value;
            } else {
                throw new NoSuchElementException("No value present");
            }
        }

        /**
         * Or else throw.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  double orElseThrow(final Supplier exceptionSupplier) throws X {
            N.checkArgNotNull(exceptionSupplier, "exceptionSupplier");

            if (isPresent) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         *
         * @return
         */
        public DoubleStream stream() {
            if (isPresent) {
                return DoubleStream.of(value);
            } else {
                return DoubleStream.empty();
            }
        }

        /**
         *
         * @return
         */
        public List toList() {
            if (isPresent()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         *
         * @return
         */
        public Set toSet() {
            if (isPresent()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To immutable list.
         *
         * @return
         */
        public ImmutableList toImmutableList() {
            if (isPresent()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList. empty();
            }
        }

        /**
         * To immutable set.
         *
         * @return
         */
        public ImmutableSet toImmutableSet() {
            if (isPresent()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet. empty();
            }
        }

        /**
         *
         * @return
         */
        public Optional boxed() {
            if (isPresent) {
                return Optional.of(value);
            } else {
                return Optional. empty();
            }
        }

        /**
         *
         * @return
         */
        public java.util.OptionalDouble __() {
            if (isPresent) {
                return java.util.OptionalDouble.of(value);
            } else {
                return java.util.OptionalDouble.empty();
            }
        }

        /**
         *
         * @param optional
         * @return
         */
        @Override
        public int compareTo(final OptionalDouble optional) {
            if (optional == null || !optional.isPresent) {
                return isPresent ? 1 : 0;
            }

            if (!isPresent) {
                return -1;
            }

            return Double.compare(this.get(), optional.get());
        }

        /**
         *
         * @param obj
         * @return
         */
        @SuppressFBWarnings
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof OptionalDouble other) {
                return (isPresent && other.isPresent) ? N.equals(value, other.value) : isPresent == other.isPresent;
            }

            return false;
        }

        /**
         *
         * @return
         */
        @Override
        public int hashCode() {
            return N.hashCode(isPresent) * 31 + N.hashCode(value);
        }

        /**
         *
         * @return
         */
        @Override
        public String toString() {
            if (isPresent) {
                return String.format("OptionalDouble[%s]", value);
            }

            return "OptionalDouble.empty";
        }
    }

    /**
     * The Class Nullable.
     *
     * @param 
     */
    @com.landawn.abacus.annotation.Immutable
    public static final class Nullable implements Immutable {

        /** Presents {@code Boolean.TRUE}. */
        public static final Nullable TRUE = new Nullable<>(Boolean.TRUE);

        /** Presents {@code Boolean.FALSE}. */
        public static final Nullable FALSE = new Nullable<>(Boolean.FALSE);

        private static final Nullable NULL_STRING = new Nullable<>(null);

        private static final Nullable EMPTY_STRING = new Nullable<>(N.EMPTY_STRING);

        /** The Constant EMPTY. */
        private static final Nullable EMPTY = new Nullable<>();

        /** The value. */
        private final T value;

        /** The is present. */
        private final boolean isPresent;

        /**
         * Instantiates a new nullable.
         */
        private Nullable() {
            this.value = null;
            this.isPresent = false;
        }

        /**
         * Instantiates a new nullable.
         *
         * @param value
         */
        private Nullable(T value) {
            this.value = value;
            this.isPresent = true;
        }

        /**
         *
         * @param 
         * @return
         */
        public static  Nullable empty() {
            return (Nullable) EMPTY;
        }

        public static Nullable of(final String value) {
            if (value == null) {
                return NULL_STRING;
            } else if (value.length() == 0) {
                return EMPTY_STRING;
            }

            return new Nullable<>(value);
        }

        /**
         *
         * @param 
         * @param value
         * @return
         */
        public static  Nullable of(final T value) {
            return new Nullable<>(value);
        }

        /**
         *
         * @param 
         * @param optional
         * @return
         */
        public static  Nullable from(Optional optional) {
            if (optional.isPresent()) {
                return new Nullable<>(optional.get());
            } else {
                return Nullable. empty();
            }
        }

        /**
         *
         * @param 
         * @param optional
         * @return
         */
        public static  Nullable from(java.util.Optional optional) {
            if (optional.isPresent()) {
                return new Nullable<>(optional.get());
            } else {
                return Nullable. empty();
            }
        }

        /**
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public T get() throws NoSuchElementException {
            return orElseThrow();
        }

        /**
         * Returns {@code true} if the value is present, otherwise returns {@code false}.
         *
         * @return true, if is present
         */
        public boolean isPresent() {
            return isPresent;
        }

        /**
         * Returns {@code true} if the value is not present, otherwise returns {@code false}.
         *
         * @return true, if is not present
         */
        public boolean isNotPresent() {
            return !isPresent;
        }

        /**
         * Returns {@code true} if the value is not present, otherwise returns {@code false}.
         *
         * @return true, if is empty
         * @deprecated replaced by {@link #isNotPresent()}
         */
        @Deprecated
        public boolean isEmpty() {
            return !isPresent;
        }

        /**
         * Returns {@code true} if the value is not present, or it is present but it's {@code null}, otherwise returns {@code false}.
         *
         * @return true, if is null
         */
        public boolean isNull() {
            return value == null;
        }

        /**
         * Returns {@code true} if the value is present and it's not {@code null}, otherwise returns {@code false}.
         *
         * @return true, if is not null
         */
        public boolean isNotNull() {
            return value != null;
        }

        /**
         *
         * @param 
         * @param action
         * @return itself
         * @throws E the e
         */
        public  Nullable ifPresent(final Throwables.Consumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isPresent()) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If present or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return itself
         * @throws E the e
         * @throws E2 the e2
         */
        public  Nullable ifPresentOrElse(final Throwables.Consumer action,
                Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isPresent()) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         * If not null.
         *
         * @param 
         * @param action
         * @return itself
         * @throws E the e
         */
        public  Nullable ifNotNull(final Throwables.Consumer action) throws E {
            N.checkArgNotNull(action, "action");

            if (isNotNull()) {
                action.accept(value);
            }

            return this;
        }

        /**
         * If not null or else.
         *
         * @param 
         * @param 
         * @param action
         * @param emptyAction
         * @return itself
         * @throws E the e
         * @throws E2 the e2
         */
        public  Nullable ifNotNullOrElse(final Throwables.Consumer action,
                Throwables.Runnable emptyAction) throws E, E2 {
            N.checkArgNotNull(action, "action");
            N.checkArgNotNull(emptyAction, "emptyAction");

            if (isNotNull()) {
                action.accept(value);
            } else {
                emptyAction.run();
            }

            return this;
        }

        /**
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  Nullable filter(final Throwables.Predicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isPresent() && predicate.test(value)) {
                return this;
            } else {
                return empty();
            }
        }

        /**
         * Filter if not null.
         *
         * @param 
         * @param predicate
         * @return
         * @throws E the e
         */
        public  Optional filterIfNotNull(final Throwables.Predicate predicate) throws E {
            N.checkArgNotNull(predicate, "predicate");

            if (isNotNull() && predicate.test(value)) {
                return Optional.of(value);
            } else {
                return Optional.empty();
            }
        }

        /**
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable map(final Throwables.Function mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return Nullable.of((U) mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Optional mapToNonNull(final Throwables.Function mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return Optional.of((U) mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         * Map to boolean.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalBoolean mapToBoolean(final Throwables.ToBooleanFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalBoolean.of(mapper.applyAsBoolean(value));
            } else {
                return OptionalBoolean.empty();
            }
        }

        /**
         * Map to char.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalChar mapToChar(final Throwables.ToCharFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalChar.of(mapper.applyAsChar(value));
            } else {
                return OptionalChar.empty();
            }
        }

        /**
         * Map to byte.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalByte mapToByte(final Throwables.ToByteFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalByte.of(mapper.applyAsByte(value));
            } else {
                return OptionalByte.empty();
            }
        }

        /**
         * Map to short.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalShort mapToShort(final Throwables.ToShortFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalShort.of(mapper.applyAsShort(value));
            } else {
                return OptionalShort.empty();
            }
        }

        /**
         * Map to int.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt mapToInt(final Throwables.ToIntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalInt.of(mapper.applyAsInt(value));
            } else {
                return OptionalInt.empty();
            }
        }

        /**
         * Map to long.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalLong mapToLong(final Throwables.ToLongFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalLong.of(mapper.applyAsLong(value));
            } else {
                return OptionalLong.empty();
            }
        }

        /**
         * Map to float.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalFloat mapToFloat(final Throwables.ToFloatFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalFloat.of(mapper.applyAsFloat(value));
            } else {
                return OptionalFloat.empty();
            }
        }

        /**
         * Map to double.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalDouble mapToDouble(final Throwables.ToDoubleFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return OptionalDouble.of(mapper.applyAsDouble(value));
            } else {
                return OptionalDouble.empty();
            }
        }

        /**
         * Map if not null.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable mapIfNotNull(final Throwables.Function mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return Nullable.of((U) mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         * Map if not null.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Optional mapToNonNullIfNotNull(final Throwables.Function mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return Optional.of((U) mapper.apply(value));
            } else {
                return Optional. empty();
            }
        }

        /**
         * Map to boolean if not null.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalBoolean mapToBooleanIfNotNull(final Throwables.ToBooleanFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return OptionalBoolean.of(mapper.applyAsBoolean(value));
            } else {
                return OptionalBoolean.empty();
            }
        }

        /**
         * Map to char if not null.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalChar mapToCharIfNotNull(final Throwables.ToCharFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return OptionalChar.of(mapper.applyAsChar(value));
            } else {
                return OptionalChar.empty();
            }
        }

        /**
         * Map to byte if not null.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalByte mapToByteIfNotNull(final Throwables.ToByteFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return OptionalByte.of(mapper.applyAsByte(value));
            } else {
                return OptionalByte.empty();
            }
        }

        /**
         * Map to short if not null.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalShort mapToShortIfNotNull(final Throwables.ToShortFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return OptionalShort.of(mapper.applyAsShort(value));
            } else {
                return OptionalShort.empty();
            }
        }

        /**
         * Map to int if not null.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalInt mapToIntIfNotNull(final Throwables.ToIntFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return OptionalInt.of(mapper.applyAsInt(value));
            } else {
                return OptionalInt.empty();
            }
        }

        /**
         * Map to long if not null.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalLong mapToLongIfNotNull(final Throwables.ToLongFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return OptionalLong.of(mapper.applyAsLong(value));
            } else {
                return OptionalLong.empty();
            }
        }

        /**
         * Map to float if not null.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalFloat mapToFloatIfNotNull(final Throwables.ToFloatFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return OptionalFloat.of(mapper.applyAsFloat(value));
            } else {
                return OptionalFloat.empty();
            }
        }

        /**
         * Map to double if not null.
         *
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  OptionalDouble mapToDoubleIfNotNull(final Throwables.ToDoubleFunction mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return OptionalDouble.of(mapper.applyAsDouble(value));
            } else {
                return OptionalDouble.empty();
            }
        }

        /**
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable flatMap(final Throwables.Function, E> mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isPresent()) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        /**
         * Flat map if not null.
         *
         * @param 
         * @param 
         * @param mapper
         * @return
         * @throws E the e
         */
        public  Nullable flatMapIfNotNull(final Throwables.Function, E> mapper) throws E {
            N.checkArgNotNull(mapper, "mapper");

            if (isNotNull()) {
                return Objects.requireNonNull(mapper.apply(value));
            } else {
                return empty();
            }
        }

        public boolean contains(final T element) {
            return isPresent() && N.equals(this.value, element);
        }

        /**
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  Nullable or(final Throwables.Supplier, E> supplier) throws E {
            N.checkArgNotNull(supplier, "supplier");

            if (isPresent()) {
                return this;
            } else {
                return Objects.requireNonNull((Nullable) supplier.get());
            }
        }

        /**
         * Or if null.
         *
         * @param 
         * @param supplier
         * @return
         * @throws E the e
         */
        public  Nullable orIfNull(final Throwables.Supplier, E> supplier) throws E {
            N.checkArgNotNull(supplier, "supplier");

            if (isNotNull()) {
                return this;
            } else {
                return Objects.requireNonNull((Nullable) supplier.get());
            }
        }

        /**
         *
         * @return
         * @deprecated using {@link #orElseNull()}
         */
        @Deprecated
        public T orNull() {
            return isPresent() ? value : null;
        }

        /**
         *
         * @return
         */
        public T orElseNull() {
            return isPresent() ? value : null;
        }

        /**
         *
         * @param other
         * @return
         */
        public T orElse(T other) {
            return isPresent() ? value : other;
        }

        /**
         * Or else get.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  T orElseGet(final Throwables.Supplier other) throws E {
            N.checkArgNotNull(other, "other");

            if (isPresent()) {
                return value;
            } else {
                return other.get();
            }
        }

        /**
         * Or else throw.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public T orElseThrow() throws NoSuchElementException {
            if (isPresent()) {
                return value;
            } else {
                throw new NoSuchElementException("No value is present");
            }
        }

        /**
         * Or else throw.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  T orElseThrow(final Supplier exceptionSupplier) throws X {
            N.checkArgNotNull(exceptionSupplier, "exceptionSupplier");

            if (isPresent()) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         * Or else if null.
         *
         * @param other
         * @return
         */
        public T orElseIfNull(T other) {
            return isNotNull() ? value : other;
        }

        /**
         * Or else get if null.
         *
         * @param 
         * @param other
         * @return
         * @throws E the e
         */
        public  T orElseGetIfNull(final Throwables.Supplier other) throws E {
            N.checkArgNotNull(other, "other");

            if (isNotNull()) {
                return value;
            } else {
                return other.get();
            }
        }

        /**
         * Or else throw if null.
         *
         * @return
         * @throws NoSuchElementException the no such element exception
         */
        public T orElseThrowIfNull() throws NoSuchElementException {
            if (isNotNull()) {
                return value;
            } else {
                throw new NoSuchElementException("No value is present");
            }
        }

        /**
         * Or else throw if null.
         *
         * @param 
         * @param exceptionSupplier
         * @return
         * @throws X the x
         */
        public  T orElseThrowIfNull(final Supplier exceptionSupplier) throws X {
            N.checkArgNotNull(exceptionSupplier, "exceptionSupplier");

            if (isNotNull()) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }

        /**
         *
         * @return
         */
        public Stream stream() {
            if (isPresent()) {
                return Stream.of(value);
            } else {
                return Stream. empty();
            }
        }

        /**
         * Stream if not null.
         *
         * @return
         */
        public Stream streamIfNotNull() {
            if (isNotNull()) {
                return Stream.of(value);
            } else {
                return Stream. empty();
            }
        }

        /**
         *
         * @return
         */
        public List toList() {
            if (isPresent()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         * To list if not null.
         *
         * @return
         */
        public List toListIfNotNull() {
            if (isNotNull()) {
                return N.asList(value);
            } else {
                return new ArrayList<>();
            }
        }

        /**
         *
         * @return
         */
        public Set toSet() {
            if (isPresent()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To set if not null.
         *
         * @return
         */
        public Set toSetIfNotNull() {
            if (isNotNull()) {
                return N.asSet(value);
            } else {
                return N.newHashSet();
            }
        }

        /**
         * To immutable list.
         *
         * @return
         */
        public ImmutableList toImmutableList() {
            if (isPresent()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList.empty();
            }
        }

        /**
         * To immutable list if not null.
         *
         * @return
         */
        public ImmutableList toImmutableListIfNotNull() {
            if (isNotNull()) {
                return ImmutableList.of(value);
            } else {
                return ImmutableList.empty();
            }
        }

        /**
         * To immutable set.
         *
         * @return
         */
        public ImmutableSet toImmutableSet() {
            if (isPresent()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet.empty();
            }
        }

        /**
         * To immutable set if not null.
         *
         * @return
         */
        public ImmutableSet toImmutableSetIfNotNull() {
            if (isNotNull()) {
                return ImmutableSet.of(value);
            } else {
                return ImmutableSet.empty();
            }
        }

        /**
         * Returns an empty {@code Optional} if it's empty or value is null.
         *
         * @return
         */
        public Optional toOptional() {
            if (value == null) {
                return Optional. empty();
            } else {
                return Optional.of(value);
            }
        }

        /**
         * Returns an empty {@code java.util.Optional} if it's empty or value is null.
         *
         * @return
         */
        public java.util.Optional toJdkOptional() {
            if (value == null) {
                return java.util.Optional. empty();
            } else {
                return java.util.Optional.of(value);
            }
        }

        /**
         *
         * @param obj
         * @return
         */
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof Nullable) {
                final Nullable other = (Nullable) obj;

                return N.equals(isPresent, other.isPresent) && N.equals(value, other.value);
            }

            return false;
        }

        /**
         *
         * @return
         */
        @Override
        public int hashCode() {
            return N.hashCode(isPresent) * 31 + N.hashCode(value);
        }

        /**
         *
         * @return
         */
        @Override
        public String toString() {
            if (value == null) {
                return isPresent ? "Nullable[null]" : "Nullable.empty";
            } else {
                return String.format("Nullable[%s]", N.toString(value));
            }
        }
    }
}