001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.lang3.tuple;
018
019import java.util.Map;
020import java.util.Objects;
021
022/**
023 * An immutable pair consisting of two {@link Object} elements.
024 *
025 * <p>
026 * Although the implementation is immutable, there is no restriction on the objects
027 * that may be stored. If mutable objects are stored in the pair, then the pair
028 * itself effectively becomes mutable.
029 * </p>
030 *
031 * <p>
032 * #ThreadSafe# if both paired objects are thread-safe
033 * </p>
034 *
035 * @param <L> The left element type
036 * @param <R> The right element type
037 * @since 3.0
038 */
039public class ImmutablePair<L, R> extends Pair<L, R> {
040
041    /**
042     * An empty array.
043     * <p>
044     * Consider using {@link #emptyArray()} to avoid generics warnings.
045     * </p>
046     *
047     * @since 3.10
048     */
049    public static final ImmutablePair<?, ?>[] EMPTY_ARRAY = {};
050
051    /**
052     * An immutable pair of nulls.
053     */
054    // This is not defined with generics to avoid warnings in call sites.
055    @SuppressWarnings("rawtypes")
056    private static final ImmutablePair NULL = new ImmutablePair<>(null, null);
057
058    /** Serialization version */
059    private static final long serialVersionUID = 4954918890077093841L;
060
061    /**
062     * Returns the empty array singleton that can be assigned without compiler warning.
063     *
064     * @param <L> The left element type
065     * @param <R> The right element type
066     * @return The empty array singleton that can be assigned without compiler warning.
067     * @since 3.10
068     */
069    @SuppressWarnings("unchecked")
070    public static <L, R> ImmutablePair<L, R>[] emptyArray() {
071        return (ImmutablePair<L, R>[]) EMPTY_ARRAY;
072    }
073
074    /**
075     * Creates an immutable pair of two objects inferring the generic types.
076     *
077     * @param <L> The left element type.
078     * @param <R> The right element type.
079     * @param left  The left element, may be null.
080     * @return An immutable formed from the two parameters, not null.
081     * @since 3.11
082     */
083    public static <L, R> Pair<L, R> left(final L left) {
084        return of(left, null);
085    }
086
087    /**
088     * Returns an immutable pair of nulls.
089     *
090     * @param <L> The left element of this pair. Value is {@code null}.
091     * @param <R> The right element of this pair. Value is {@code null}.
092     * @return An immutable pair of nulls.
093     * @since 3.6
094     */
095    @SuppressWarnings("unchecked")
096    public static <L, R> ImmutablePair<L, R> nullPair() {
097        return NULL;
098    }
099
100    /**
101     * Creates an immutable pair of two objects inferring the generic types.
102     *
103     * @param <L> The left element type.
104     * @param <R> The right element type.
105     * @param left  The left element, may be null.
106     * @param right  The right element, may be null.
107     * @return An immutable formed from the two parameters, not null.
108     */
109    public static <L, R> ImmutablePair<L, R> of(final L left, final R right) {
110        return left != null || right != null ? new ImmutablePair<>(left, right) : nullPair();
111    }
112
113    /**
114     * Creates an immutable pair from a map entry.
115     *
116     * @param <L> The left element type.
117     * @param <R> The right element type.
118     * @param pair The existing map entry.
119     * @return An immutable formed from the map entry.
120     * @since 3.10
121     */
122    public static <L, R> ImmutablePair<L, R> of(final Map.Entry<L, R> pair) {
123        return pair != null ? new ImmutablePair<>(pair.getKey(), pair.getValue()) : nullPair();
124    }
125
126    /**
127     * Creates an immutable pair of two non-null objects inferring the generic types.
128     *
129     * @param <L> The left element type.
130     * @param <R> The right element type.
131     * @param left  The left element, may not be null.
132     * @param right  The right element, may not  be null.
133     * @return An immutable formed from the two parameters, not null.
134     * @throws NullPointerException Thrown if any input is null.
135     * @since 3.13.0
136     */
137    public static <L, R> ImmutablePair<L, R> ofNonNull(final L left, final R right) {
138        return of(Objects.requireNonNull(left, "left"), Objects.requireNonNull(right, "right"));
139    }
140
141    /**
142     * Creates an immutable pair of two objects inferring the generic types.
143     *
144     * @param <L> The left element type.
145     * @param <R> The right element type.
146     * @param right  The right element, may be null.
147     * @return An immutable formed from the two parameters, not null.
148     * @since 3.11
149     */
150    public static <L, R> Pair<L, R> right(final R right) {
151        return of(null, right);
152    }
153
154    /** Left object */
155    public final L left;
156
157    /** Right object */
158    public final R right;
159
160    /**
161     * Create a new pair instance.
162     *
163     * @param left  The left value, may be null
164     * @param right  The right value, may be null
165     */
166    public ImmutablePair(final L left, final R right) {
167        this.left = left;
168        this.right = right;
169    }
170
171    /**
172     * {@inheritDoc}
173     */
174    @Override
175    public L getLeft() {
176        return left;
177    }
178
179    /**
180     * {@inheritDoc}
181     */
182    @Override
183    public R getRight() {
184        return right;
185    }
186
187    /**
188     * Sets no value and always throws {@link UnsupportedOperationException}.
189     *
190     * <p>
191     * This pair is immutable, so this operation is not supported.
192     * </p>
193     *
194     * @param value  The value to set
195     * @return never
196     * @throws UnsupportedOperationException Thrown because this operation is not supported.
197     */
198    @Override
199    public R setValue(final R value) {
200        throw new UnsupportedOperationException();
201    }
202
203}