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.Objects;
20  
21  /**
22   * An immutable triple consisting of three {@link Object} elements.
23   *
24   * <p>
25   * Although the implementation is immutable, there is no restriction on the objects
26   * that may be stored. If mutable objects are stored in the triple, then the triple
27   * itself effectively becomes mutable.
28   * </p>
29   *
30   * <p>
31   * #ThreadSafe# if all three objects are thread-safe.
32   * </p>
33   *
34   * @param <L> The left element type.
35   * @param <M> The middle element type.
36   * @param <R> The right element type.
37   * @since 3.2
38   */
39  public class ImmutableTriple<L, M, R> extends Triple<L, M, 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 ImmutableTriple<?, ?, ?>[] EMPTY_ARRAY = {};
50  
51      /**
52       * An immutable triple of nulls.
53       */
54      // This is not defined with generics to avoid warnings in call sites.
55      @SuppressWarnings("rawtypes")
56      private static final ImmutableTriple NULL = new ImmutableTriple<>(null, null, null);
57  
58      /** Serialization version. */
59      private static final long serialVersionUID = 1L;
60  
61      /**
62       * Gets the empty array singleton that can be assigned without compiler warning.
63       *
64       * @param <L> The left element type.
65       * @param <M> The middle element type.
66       * @param <R> The right element type.
67       * @return The empty array singleton that can be assigned without compiler warning.
68       * @since 3.10
69       */
70      @SuppressWarnings("unchecked")
71      public static <L, M, R> ImmutableTriple<L, M, R>[] emptyArray() {
72          return (ImmutableTriple<L, M, R>[]) EMPTY_ARRAY;
73      }
74  
75      /**
76       * Gets the immutable triple of nulls singleton.
77       *
78       * @param <L> The left element of this triple. Value is {@code null}.
79       * @param <M> The middle element of this triple. Value is {@code null}.
80       * @param <R> The right element of this triple. Value is {@code null}.
81       * @return An immutable triple of nulls.
82       * @since 3.6
83       */
84      @SuppressWarnings("unchecked")
85      public static <L, M, R> ImmutableTriple<L, M, R> nullTriple() {
86          return NULL;
87      }
88  
89      /**
90       * Creates an immutable triple of three objects inferring the generic types.
91       *
92       * @param <L> The left element type.
93       * @param <M> The middle element type.
94       * @param <R> The right element type.
95       * @param left  The left element, may be null.
96       * @param middle  The middle element, may be null.
97       * @param right  The right element, may be null.
98       * @return An immutable triple formed from the three parameters, not null.
99       */
100     public static <L, M, R> ImmutableTriple<L, M, R> of(final L left, final M middle, final R right) {
101         return left != null | middle != null || right != null ? new ImmutableTriple<>(left, middle, right) : nullTriple();
102     }
103 
104     /**
105      * Creates an immutable triple of three non-null objects inferring the generic types.
106      *
107      * @param <L> The left element type.
108      * @param <M> The middle element type.
109      * @param <R> The right element type.
110      * @param left  The left element, may not be null.
111      * @param middle  The middle element, may not be null.
112      * @param right  The right element, may not be null.
113      * @return An immutable triple formed from the three parameters, not null.
114      * @throws NullPointerException Thrown if any input is null.
115      * @since 3.13.0
116      */
117     public static <L, M, R> ImmutableTriple<L, M, R> ofNonNull(final L left, final M middle, final R right) {
118         return of(Objects.requireNonNull(left, "left"), Objects.requireNonNull(middle, "middle"), Objects.requireNonNull(right, "right"));
119     }
120 
121     /** Left object. */
122 
123     public final L left;
124 
125     /** Middle object. */
126     public final M middle;
127 
128     /** Right object. */
129     public final R right;
130 
131     /**
132      * Constructs a new triple instance.
133      *
134      * @param left  The left value, may be null.
135      * @param middle The middle value, may be null.
136      * @param right  The right value, may be null.
137      */
138     public ImmutableTriple(final L left, final M middle, final R right) {
139         this.left = left;
140         this.middle = middle;
141         this.right = right;
142     }
143 
144     /**
145      * {@inheritDoc}
146      */
147     @Override
148     public L getLeft() {
149         return left;
150     }
151 
152     /**
153      * {@inheritDoc}
154      */
155     @Override
156     public M getMiddle() {
157         return middle;
158     }
159 
160     /**
161      * {@inheritDoc}
162      */
163     @Override
164     public R getRight() {
165         return right;
166     }
167 }
168