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 4 objects. 027 * 028 * <p> 029 * This class is useful when you need a four-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 Tuple5} 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 */ 050public class Tuple4<A,B,C,D> { 051 052 /** 053 * Static creator. 054 * 055 * @param <A> Object 1 type. 056 * @param <B> Object 2 type. 057 * @param <C> Object 3 type. 058 * @param <D> Object 4 type. 059 * @param a Object 1. 060 * @param b Object 2. 061 * @param c Object 3. 062 * @param d Object 4. 063 * @return A new tuple object. 064 */ 065 public static <A,B,C,D> Tuple4<A,B,C,D> of(A a, B b, C c, D d) { 066 return new Tuple4<>(a, b, c, d); 067 } 068 069 private final A a; 070 private final B b; 071 private final C c; 072 private final D d; 073 private final int hashCode; 074 075 /** 076 * Constructor. 077 * 078 * @param a Object 1. 079 * @param b Object 2. 080 * @param c Object 3. 081 * @param d Object 4. 082 */ 083 public Tuple4(A a, B b, C c, D d) { 084 this.a = a; 085 this.b = b; 086 this.c = c; 087 this.d = d; 088 this.hashCode = h(a, b, c, d); 089 } 090 091 @Override /* Overridden from Object */ 092 public boolean equals(Object o) { 093 return o instanceof Tuple4<?,?,?,?> 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)); 094 } 095 096 /** 097 * Returns the first object in this tuple. 098 * 099 * @return The first object in this tuple. 100 */ 101 public A getA() { return a; } 102 103 /** 104 * Returns the second object in this tuple. 105 * 106 * @return The second object in this tuple. 107 */ 108 public B getB() { return b; } 109 110 /** 111 * Returns the third object in this tuple. 112 * 113 * @return The third object in this tuple. 114 */ 115 public C getC() { return c; } 116 117 /** 118 * Returns the fourth object in this tuple. 119 * 120 * @return The fourth object in this tuple. 121 */ 122 public D getD() { return d; } 123 124 /** 125 * Returns the first object in this tuple wrapped in an {@link Optional}. 126 * 127 * @return The first object wrapped in an Optional, or Optional.empty() if the value is null. 128 */ 129 public Optional<A> optA() { 130 return Optional.ofNullable(a); 131 } 132 133 /** 134 * Returns the second object in this tuple wrapped in an {@link Optional}. 135 * 136 * @return The second object wrapped in an Optional, or Optional.empty() if the value is null. 137 */ 138 public Optional<B> optB() { 139 return Optional.ofNullable(b); 140 } 141 142 /** 143 * Returns the third object in this tuple wrapped in an {@link Optional}. 144 * 145 * @return The third object wrapped in an Optional, or Optional.empty() if the value is null. 146 */ 147 public Optional<C> optC() { 148 return Optional.ofNullable(c); 149 } 150 151 /** 152 * Returns the fourth object in this tuple wrapped in an {@link Optional}. 153 * 154 * @return The fourth object wrapped in an Optional, or Optional.empty() if the value is null. 155 */ 156 public Optional<D> optD() { 157 return Optional.ofNullable(d); 158 } 159 160 @Override /* Overridden from Object */ 161 public int hashCode() { 162 return hashCode; 163 } 164}