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 *      http://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.juneau.commons.function;
018
019import static org.apache.juneau.commons.utils.Utils.*;
020
021import java.util.Optional;
022
023import org.apache.juneau.commons.lang.*;
024
025/**
026 * Represents a simple tuple of 5 objects.
027 *
028 * <p>
029 * This class is useful when you need a five-value composite key for HashMap lookups that properly implements
030 * {@link #equals(Object)} and {@link #hashCode()} based on content rather than identity.
031 *
032 * <h5 class='section'>Array Support:</h5>
033 * <p>
034 * Unlike using arrays directly as HashMap keys, this class properly handles arrays by using
035 * content-based equality and hashing via {@link HashCode#of(Object...)} which internally uses
036 * {@link java.util.Arrays#hashCode(Object[])} for arrays.
037 *
038 * <h5 class='section'>See Also:</h5><ul>
039 *    <li class='jc'>{@link Tuple1}
040 *    <li class='jc'>{@link Tuple2}
041 *    <li class='jc'>{@link Tuple3}
042 *    <li class='jc'>{@link Tuple4}
043 * </ul>
044 *
045 * @param <A> Object 1 type.
046 * @param <B> Object 2 type.
047 * @param <C> Object 3 type.
048 * @param <D> Object 4 type.
049 * @param <E> Object 5 type.
050 */
051public class Tuple5<A,B,C,D,E> {
052
053   /**
054    * Static creator.
055    *
056    * @param <A> Object 1 type.
057    * @param <B> Object 2 type.
058    * @param <C> Object 3 type.
059    * @param <D> Object 4 type.
060    * @param <E> Object 5 type.
061    * @param a Object 1.
062    * @param b Object 2.
063    * @param c Object 3.
064    * @param d Object 4.
065    * @param e Object 5.
066    * @return A new tuple object.
067    */
068   public static <A,B,C,D,E> Tuple5<A,B,C,D,E> of(A a, B b, C c, D d, E e) {
069      return new Tuple5<>(a, b, c, d, e);
070   }
071
072   private final A a;
073   private final B b;
074   private final C c;
075   private final D d;
076   private final E e;
077   private final int hashCode;
078
079   /**
080    * Constructor.
081    *
082    * @param a Object 1.
083    * @param b Object 2.
084    * @param c Object 3.
085    * @param d Object 4.
086    * @param e Object 5.
087    */
088   public Tuple5(A a, B b, C c, D d, E e) {
089      this.a = a;
090      this.b = b;
091      this.c = c;
092      this.d = d;
093      this.e = e;
094      this.hashCode = h(a, b, c, d, e);
095   }
096
097   @Override /* Overridden from Object */
098   public boolean equals(Object o) {
099      return o instanceof Tuple5<?,?,?,?,?> o2 && eq(this, o2, (x, y) -> eq(x.a, y.a) && eq(x.b, y.b) && eq(x.c, y.c) && eq(x.d, y.d) && eq(x.e, y.e));
100   }
101
102   /**
103    * Returns the first object in this tuple.
104    *
105    * @return The first object in this tuple.
106    */
107   public A getA() { return a; }
108
109   /**
110    * Returns the second object in this tuple.
111    *
112    * @return The second object in this tuple.
113    */
114   public B getB() { return b; }
115
116   /**
117    * Returns the third object in this tuple.
118    *
119    * @return The third object in this tuple.
120    */
121   public C getC() { return c; }
122
123   /**
124    * Returns the fourth object in this tuple.
125    *
126    * @return The fourth object in this tuple.
127    */
128   public D getD() { return d; }
129
130   /**
131    * Returns the fifth object in this tuple.
132    *
133    * @return The fifth object in this tuple.
134    */
135   public E getE() { return e; }
136
137   /**
138    * Returns the first object in this tuple wrapped in an {@link Optional}.
139    *
140    * @return The first object wrapped in an Optional, or Optional.empty() if the value is null.
141    */
142   public Optional<A> optA() {
143      return Optional.ofNullable(a);
144   }
145
146   /**
147    * Returns the second object in this tuple wrapped in an {@link Optional}.
148    *
149    * @return The second object wrapped in an Optional, or Optional.empty() if the value is null.
150    */
151   public Optional<B> optB() {
152      return Optional.ofNullable(b);
153   }
154
155   /**
156    * Returns the third object in this tuple wrapped in an {@link Optional}.
157    *
158    * @return The third object wrapped in an Optional, or Optional.empty() if the value is null.
159    */
160   public Optional<C> optC() {
161      return Optional.ofNullable(c);
162   }
163
164   /**
165    * Returns the fourth object in this tuple wrapped in an {@link Optional}.
166    *
167    * @return The fourth object wrapped in an Optional, or Optional.empty() if the value is null.
168    */
169   public Optional<D> optD() {
170      return Optional.ofNullable(d);
171   }
172
173   /**
174    * Returns the fifth object in this tuple wrapped in an {@link Optional}.
175    *
176    * @return The fifth object wrapped in an Optional, or Optional.empty() if the value is null.
177    */
178   public Optional<E> optE() {
179      return Optional.ofNullable(e);
180   }
181
182   @Override /* Overridden from Object */
183   public int hashCode() {
184      return hashCode;
185   }
186}