View Javadoc
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 }