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

com.landawn.abacus.util.Pair 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.

The newest version!
/*
 * Copyright (c) 2015, 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.Map;

import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.annotation.SuppressFBWarnings;
import com.landawn.abacus.util.Tuple.Tuple2;
import com.landawn.abacus.util.u.Optional;

/**
 *
 * @param 
 * @param 
 */
@SuppressFBWarnings("PA_PUBLIC_PRIMITIVE_ATTRIBUTE")
public final class Pair implements Map.Entry, Mutable {
    // implements Map.Entry {
    public L left; //NOSONAR

    public R right; //NOSONAR

    public Pair() {
    }

    Pair(final L l, final R r) {
        left = l;
        right = r;
    }

    /**
     *
     * @param 
     * @param 
     * @param l
     * @param r
     * @return
     */
    public static  Pair of(final L l, final R r) {
        return new Pair<>(l, r);
    }

    /**
     * Create a new {@code Pair} with the values from the specified {@code entry}.
     *
     * @param  the key type
     * @param  the value type
     * @param entry
     * @return
     */
    public static  Pair create(final Map.Entry entry) {
        return new Pair<>(entry.getKey(), entry.getValue());
    }

    private static final Pair[] EMPTY_ARRAY = new Pair[0];

    /**
     *
     * @param 
     * @param 
     * @return
     */
    @SuppressWarnings("unchecked")
    public static  Pair[] emptyArray() {
        return (Pair[]) EMPTY_ARRAY;
    }

    /**
     * Gets the left.
     *
     * @return
     */
    public L getLeft() {
        return left;
    }

    /**
     * Sets the left.
     *
     * @param left the new left
     */
    public void setLeft(final L left) {
        this.left = left;
    }

    /**
     * Gets the right.
     *
     * @return
     */
    public R getRight() {
        return right;
    }

    /**
     * Sets the right.
     *
     * @param right the new right
     */
    public void setRight(final R right) {
        this.right = right;
    }

    /**
     *
     * @param left
     * @param right
     */
    public void set(final L left, final R right) {
        this.left = left;
        this.right = right;
    }

    /**
     * Returns the current left value and then sets it with the specified value.
     *
     * @param newLeft
     * @return
     */
    public L getAndSetLeft(final L newLeft) {
        final L res = left;
        left = newLeft;
        return res;
    }

    /**
     * Sets left with the specified value and then return it.
     *
     * @param newLeft
     * @return
     */
    public L setAndGetLeft(final L newLeft) {
        left = newLeft;
        return left;
    }

    /**
     Returns the current right value and then sets it with the specified value.
     *
     * @param newRight
     * @return
     */
    public R getAndSetRight(final R newRight) {
        final R res = right;
        right = newRight;
        return res;
    }

    /**
     * Sets right with the specified value and then return it.
     *
     * @param newRight
     * @return
     */
    public R setAndGetRight(final R newRight) {
        right = newRight;
        return right;
    }

    /**
     * Set to the specified {@code newLeft} and returns {@code true}
     * if {@code predicate} returns {@code true}. Otherwise returns
     * {@code false} without setting the value to new value.
     *
     * @param 
     * @param newLeft
     * @param predicate - the first parameter is current pair, the second
     *        parameter is the {@code newLeft}
     * @return
     * @throws E the e
     */
    public  boolean setLeftIf(final L newLeft, final Throwables.BiPredicate, ? super L, E> predicate) throws E {
        if (predicate.test(this, newLeft)) {
            left = newLeft;
            return true;
        }

        return false;
    }

    /**
     * Set to the specified {@code newRight} and returns {@code true}
     * if {@code predicate} returns {@code true}. Otherwise returns
     * {@code false} without setting the value to new value.
     *
     * @param 
     * @param newRight
     * @param predicate - the first parameter is current pair, the second
     *        parameter is the {@code newRight}
     * @return
     * @throws E the e
     */
    public  boolean setRightIf(final R newRight, final Throwables.BiPredicate, ? super R, E> predicate) throws E {
        if (predicate.test(this, newRight)) {
            right = newRight;
            return true;
        }

        return false;
    }

    /**
     * Set to the specified {@code newLeft} and {@code newRight} and returns {@code true}
     * if {@code predicate} returns {@code true}. Otherwise returns
     * {@code false} without setting the left/right to new values.
     *
     * @param 
     * @param newLeft
     * @param newRight
     * @param predicate - the first parameter is current pair, the second
     *        parameter is the {@code newLeft}, the third parameter is the {@code newRight}.
     * @return
     * @throws E the e
     */
    public  boolean setIf(final L newLeft, final R newRight,
            final Throwables.TriPredicate, ? super L, ? super R, E> predicate) throws E {
        if (predicate.test(this, newLeft, newRight)) {
            left = newLeft;
            right = newRight;
            return true;
        }

        return false;
    }
    //
    //    /**
    //     *
    //     * @deprecated don't access this method by {@code Pair} interface.
    //     */
    //    @Deprecated
    //    @Override
    //    public L getKey() {
    //        return left;
    //    }
    //
    //    /**
    //     *
    //     * @deprecated don't access this method by {@code Pair} interface.
    //     */
    //    @Deprecated
    //    @Override
    //    public R getValue() {
    //        return right;
    //    }
    //
    //    /**
    //     *
    //     * @deprecated don't access this method by {@code Pair} interface.
    //     */
    //    @Deprecated
    //    @Override
    //    public R setValue(R value) {
    //        R oldValue = this.right;
    //        this.right = value;
    //
    //        return oldValue;
    //    }

    //    public R getAndSetValue(R newRight) {
    //        return getAndSetRight(newRight);
    //    }
    //
    //    public R setAndGetValue(R newRight) {
    //        return setAndGetRight(newRight);
    //    }
    //
    //    /**
    //     *
    //     * @param newRight
    //     * @param predicate
    //     * @return
    //     * @see #setRightIf(Object, BiPredicate)
    //     */
    //    public boolean setValueIf(final R newRight, BiPredicate, ? super R> predicate) {
    //        return setRightIf(newRight, predicate);
    //    }

    /**
     * Returns a new instance of Pair<R, L>.
     *
     * @return a new instance of Pair<R, L>.
     */
    @Beta
    public Pair reverse() {
        return new Pair<>(right, left);
    }

    public Pair copy() {
        return new Pair<>(left, right);
    }

    public Object[] toArray() {
        return new Object[] { left, right };
    }

    /**
     *
     * @param 
     * @param a
     * @return
     */
    public  A[] toArray(A[] a) {
        if (a.length < 2) {
            a = N.copyOf(a, 2);
        }

        a[0] = (A) left;
        a[1] = (A) right;

        return a;
    }

    /**
     *
     * @param 
     * @param consumer
     * @throws E the e
     */
    public  void forEach(final Throwables.Consumer consumer) throws E {
        final Throwables.Consumer objConsumer = (Throwables.Consumer) consumer;

        objConsumer.accept(left);
        objConsumer.accept(right);
    }

    /**
     *
     * @param 
     * @param action
     * @throws E the e
     */
    public  void accept(final Throwables.BiConsumer action) throws E {
        action.accept(left, right);
    }

    /**
     *
     * @param 
     * @param action
     * @throws E the e
     */
    public  void accept(final Throwables.Consumer, E> action) throws E {
        action.accept(this);
    }

    /**
     *
     * @param 
     * @param 
     * @param mapper
     * @return
     * @throws E the e
     */
    public  U map(final Throwables.BiFunction mapper) throws E {
        return mapper.apply(left, right);
    }

    /**
     *
     * @param 
     * @param 
     * @param mapper
     * @return
     * @throws E the e
     */
    public  U map(final Throwables.Function, ? extends U, E> mapper) throws E {
        return mapper.apply(this);
    }

    /**
     *
     * @param 
     * @param predicate
     * @return
     * @throws E the e
     */
    public  Optional> filter(final Throwables.BiPredicate predicate) throws E {
        return predicate.test(left, right) ? Optional.of(this) : Optional.empty();
    }

    /**
     *
     * @param 
     * @param predicate
     * @return
     * @throws E the e
     */
    public  Optional> filter(final Throwables.Predicate, E> predicate) throws E {
        return predicate.test(this) ? Optional.of(this) : Optional.empty();
    }

    //    /**
    //     *
    //     *
    //     * @return
    //     * @deprecated unlikely to be useful. It's marked to be removed.
    //     */
    //    @Deprecated
    //    @Beta
    //    public Stream> stream() {
    //        return Stream.of(this);
    //    }
    //
    //    /**
    //     *
    //     *
    //     * @param 
    //     * @param 
    //     * @param func
    //     * @return
    //     * @throws E
    //     * @deprecated unlikely to be useful. It's marked to be removed.
    //     */
    //    @Deprecated
    //    @Beta
    //    public  Stream stream(final Throwables.Function, Stream, E> func) throws E {
    //        return func.apply(this);
    //    }
    //
    //    /**
    //     *
    //     *
    //     * @return
    //     * @deprecated {@code Optional} is misused. It's marked to be removed.
    //     */
    //    @Deprecated
    //    public Optional> toOptional() {
    //        return Optional.of(this);
    //    }

    public Tuple2 toTuple() {
        return Tuple.of(left, right);
    }

    public ImmutableEntry toImmutableEntry() {
        return ImmutableEntry.of(left, right);
    }

    /**
     *
     * @return
     * @deprecated using {@link #getLeft()}
     */
    @Deprecated
    @Override
    public L getKey() {
        return left;
    }

    /**
     *
     * @return
     * @deprecated using {@link #getRight()}
     */
    @Deprecated
    @Override
    public R getValue() {
        return right;
    }

    /**
     *
     * @param value
     * @return
     * @deprecated using {@link #setRight(Object)}
     */
    @Deprecated
    @Override
    public R setValue(final R value) {
        return right;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + N.hashCode(left);
        return prime * result + N.hashCode(right);
    }

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

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

            return N.equals(left, other.left) && N.equals(right, other.right);
        }

        return false;
    }

    @Override
    public String toString() {
        return "[" + N.toString(left) + ", " + N.toString(right) + "]";
    }
}