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    *      http://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>Although the implementation is immutable, there is no restriction on the objects
26   * that may be stored. If mutable objects are stored in the pair, then the pair
27   * itself effectively becomes mutable.</p>
28   *
29   * <p>#ThreadSafe# if both paired objects are thread-safe</p>
30   *
31   * @param <L> the left element type
32   * @param <R> the right element type
33   *
34   * @since 3.0
35   */
36  public class ImmutablePair<L, R> extends Pair<L, R> {
37  
38      /**
39       * An empty array.
40       * <p>
41       * Consider using {@link #emptyArray()} to avoid generics warnings.
42       * </p>
43       *
44       * @since 3.10.
45       */
46      public static final ImmutablePair<?, ?>[] EMPTY_ARRAY = {};
47  
48      /**
49       * An immutable pair of nulls.
50       */
51      // This is not defined with generics to avoid warnings in call sites.
52      @SuppressWarnings("rawtypes")
53      private static final ImmutablePair NULL = new ImmutablePair<>(null, null);
54  
55      /** Serialization version */
56      private static final long serialVersionUID = 4954918890077093841L;
57  
58      /**
59       * Returns the empty array singleton that can be assigned without compiler warning.
60       *
61       * @param <L> the left element type
62       * @param <R> the right element type
63       * @return the empty array singleton that can be assigned without compiler warning.
64       *
65       * @since 3.10.
66       */
67      @SuppressWarnings("unchecked")
68      public static <L, R> ImmutablePair<L, R>[] emptyArray() {
69          return (ImmutablePair<L, R>[]) EMPTY_ARRAY;
70      }
71  
72      /**
73       * Creates an immutable pair of two objects inferring the generic types.
74       *
75       * <p>This factory allows the pair to be created using inference to
76       * obtain the generic types.</p>
77       *
78       * @param <L> the left element type
79       * @param <R> the right element type
80       * @param left  the left element, may be null
81       * @return a pair formed from the two parameters, not null
82       * @since 3.11
83       */
84      public static <L, R> Pair<L, R> left(final L left) {
85          return ImmutablePair.of(left, null);
86      }
87  
88      /**
89       * Returns an immutable pair of nulls.
90       *
91       * @param <L> the left element of this pair. Value is {@code null}.
92       * @param <R> the right element of this pair. Value is {@code null}.
93       * @return an immutable pair of nulls.
94       * @since 3.6
95       */
96      @SuppressWarnings("unchecked")
97      public static <L, R> ImmutablePair<L, R> nullPair() {
98          return NULL;
99      }
100 
101     /**
102      * Creates an immutable pair of two objects inferring the generic types.
103      *
104      * <p>This factory allows the pair to be created using inference to
105      * obtain the generic types.</p>
106      *
107      * @param <L> the left element type
108      * @param <R> the right element type
109      * @param left  the left element, may be null
110      * @param right  the right element, may be null
111      * @return a pair formed from the two parameters, not null
112      */
113     public static <L, R> ImmutablePair<L, R> of(final L left, final R right) {
114         return left != null || right != null ? new ImmutablePair<>(left, right) : nullPair();
115     }
116 
117     /**
118      * Creates an immutable pair from a map entry.
119      *
120      * <p>This factory allows the pair to be created using inference to
121      * obtain the generic types.</p>
122      *
123      * @param <L> the left element type
124      * @param <R> the right element type
125      * @param pair the existing map entry.
126      * @return a pair formed from the map entry
127      * @since 3.10
128      */
129     public static <L, R> ImmutablePair<L, R> of(final Map.Entry<L, R> pair) {
130         return pair != null ? new ImmutablePair<>(pair.getKey(), pair.getValue()) : nullPair();
131     }
132 
133     /**
134      * Creates an immutable pair of two non-null objects inferring the generic types.
135      *
136      * <p>This factory allows the pair to be created using inference to
137      * obtain the generic types.</p>
138      *
139      * @param <L> the left element type
140      * @param <R> the right element type
141      * @param left  the left element, may not be null
142      * @param right  the right element, may not  be null
143      * @return a pair formed from the two parameters, not null
144      * @throws NullPointerException if any input is null
145      * @since 3.13.0
146      */
147     public static <L, R> ImmutablePair<L, R> ofNonNull(final L left, final R right) {
148         return of(Objects.requireNonNull(left, "left"), Objects.requireNonNull(right, "right"));
149     }
150 
151     /**
152      * Creates an immutable pair of two objects inferring the generic types.
153      *
154      * <p>This factory allows the pair to be created using inference to
155      * obtain the generic types.</p>
156      *
157      * @param <L> the left element type
158      * @param <R> the right element type
159      * @param right  the right element, may be null
160      * @return a pair formed from the two parameters, not null
161      * @since 3.11
162      */
163     public static <L, R> Pair<L, R> right(final R right) {
164         return ImmutablePair.of(null, right);
165     }
166 
167     /** Left object */
168     public final L left;
169 
170     /** Right object */
171     public final R right;
172 
173     /**
174      * Create a new pair instance.
175      *
176      * @param left  the left value, may be null
177      * @param right  the right value, may be null
178      */
179     public ImmutablePair(final L left, final R right) {
180         this.left = left;
181         this.right = right;
182     }
183 
184     /**
185      * {@inheritDoc}
186      */
187     @Override
188     public L getLeft() {
189         return left;
190     }
191 
192     /**
193      * {@inheritDoc}
194      */
195     @Override
196     public R getRight() {
197         return right;
198     }
199 
200     /**
201      * Throws {@link UnsupportedOperationException}.
202      *
203      * <p>This pair is immutable, so this operation is not supported.</p>
204      *
205      * @param value  the value to set
206      * @return never
207      * @throws UnsupportedOperationException as this operation is not supported
208      */
209     @Override
210     public R setValue(final R value) {
211         throw new UnsupportedOperationException();
212     }
213 
214 }