1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.lang3.tuple;
18
19 import java.util.Map;
20 import java.util.Objects;
21
22 /**
23 * An immutable pair consisting of two {@link Object} elements.
24 *
25 * <p>
26 * Although the implementation is immutable, there is no restriction on the objects
27 * that may be stored. If mutable objects are stored in the pair, then the pair
28 * itself effectively becomes mutable.
29 * </p>
30 *
31 * <p>
32 * #ThreadSafe# if both paired objects are thread-safe
33 * </p>
34 *
35 * @param <L> The left element type
36 * @param <R> The right element type
37 * @since 3.0
38 */
39 public class ImmutablePair<L, R> extends Pair<L, R> {
40
41 /**
42 * An empty array.
43 * <p>
44 * Consider using {@link #emptyArray()} to avoid generics warnings.
45 * </p>
46 *
47 * @since 3.10
48 */
49 public static final ImmutablePair<?, ?>[] EMPTY_ARRAY = {};
50
51 /**
52 * An immutable pair of nulls.
53 */
54 // This is not defined with generics to avoid warnings in call sites.
55 @SuppressWarnings("rawtypes")
56 private static final ImmutablePair NULL = new ImmutablePair<>(null, null);
57
58 /** Serialization version */
59 private static final long serialVersionUID = 4954918890077093841L;
60
61 /**
62 * Returns the empty array singleton that can be assigned without compiler warning.
63 *
64 * @param <L> The left element type
65 * @param <R> The right element type
66 * @return The empty array singleton that can be assigned without compiler warning.
67 * @since 3.10
68 */
69 @SuppressWarnings("unchecked")
70 public static <L, R> ImmutablePair<L, R>[] emptyArray() {
71 return (ImmutablePair<L, R>[]) EMPTY_ARRAY;
72 }
73
74 /**
75 * Creates an immutable pair of two objects inferring the generic types.
76 *
77 * @param <L> The left element type.
78 * @param <R> The right element type.
79 * @param left The left element, may be null.
80 * @return An immutable formed from the two parameters, not null.
81 * @since 3.11
82 */
83 public static <L, R> Pair<L, R> left(final L left) {
84 return of(left, null);
85 }
86
87 /**
88 * Returns an immutable pair of nulls.
89 *
90 * @param <L> The left element of this pair. Value is {@code null}.
91 * @param <R> The right element of this pair. Value is {@code null}.
92 * @return An immutable pair of nulls.
93 * @since 3.6
94 */
95 @SuppressWarnings("unchecked")
96 public static <L, R> ImmutablePair<L, R> nullPair() {
97 return NULL;
98 }
99
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 }