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