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.Shorts.*;
020
021import java.util.*;
022
023import org.apache.juneau.commons.lang.*;
024import org.apache.juneau.commons.utils.*;
025
026/**
027 * Represents an immutable tuple containing a single value.
028 *
029 * <p>
030 * This class provides a simple wrapper for a single value that properly implements
031 * {@link #equals(Object)} and {@link #hashCode()} based on content rather than identity.
032 * This is particularly useful for HashMap keys when you want to use an array or need
033 * a wrapper that uses content-based equality.
034 *
035 * <h5 class='section'>Features:</h5>
036 * <ul class='spaced-list'>
037 *    <li>Immutable - value cannot be changed after construction
038 *    <li>Content-based equality - uses {@link Shorts#eq(Object, Object)} for comparison
039 *    <li>Content-based hashing - uses {@link HashCode#of(Object...)} for hash code computation
040 *    <li>Array support - properly handles arrays with content-based equality and hashing
041 * </ul>
042 *
043 * <h5 class='section'>Array Support:</h5>
044 * <p>
045 * Unlike using arrays directly as HashMap keys (which use identity-based equality), this class properly
046 * handles arrays by using content-based equality and hashing via {@link HashCode#of(Object...)} which
047 * internally uses {@link Arrays#hashCode(Object[])} for arrays. This means two Tuple1 instances
048 * containing arrays with the same content will be considered equal.
049 *
050 * <h5 class='section'>Use Cases:</h5>
051 * <ul class='spaced-list'>
052 *    <li>Using arrays as HashMap keys with proper content-based equality
053 *    <li>Wrapping values that need content-based equality for collections
054 *    <li>Creating composite keys from single values
055 *    <li>Passing values through APIs that require object identity preservation
056 * </ul>
057 *
058 * <h5 class='section'>Usage:</h5>
059 * <p class='bjava'>
060 *    <jc>// Using arrays as keys via Tuple1</jc>
061 *    Map&lt;Tuple1&lt;String[]&gt;,Integer&gt; <jv>map</jv> = <jk>new</jk> HashMap&lt;&gt;();
062 *    <jv>map</jv>.put(Tuple1.<jsm>of</jsm>(<jk>new</jk> String[]{<js>"a"</js>,<js>"b"</js>}), 1);
063 *    <jv>map</jv>.put(Tuple1.<jsm>of</jsm>(<jk>new</jk> String[]{<js>"a"</js>,<js>"b"</js>}), 2);  <jc>// Replaces first entry</jc>
064 *    System.<jsf>out</jsf>.println(<jv>map</jv>.size());  <jc>// Prints "1"</jc>
065 *
066 *    <jc>// Using with other types</jc>
067 *    Map&lt;Tuple1&lt;String&gt;,Integer&gt; <jv>stringMap</jv> = <jk>new</jk> HashMap&lt;&gt;();
068 *    <jv>stringMap</jv>.put(Tuple1.<jsm>of</jsm>(<js>"key"</js>), 42);
069 *    Integer <jv>value</jv> = <jv>stringMap</jv>.get(Tuple1.<jsm>of</jsm>(<js>"key"</js>));  <jc>// Returns 42</jc>
070 * </p>
071 *
072 * <h5 class='section'>Thread Safety:</h5>
073 * <p>
074 * This class is immutable and therefore thread-safe. Multiple threads can safely access a Tuple1 instance
075 * concurrently without synchronization.
076 *
077 * <h5 class='section'>See Also:</h5><ul>
078 *    <li class='jc'>{@link Tuple2} - Two-value tuple
079 *    <li class='jc'>{@link Tuple3} - Three-value tuple
080 *    <li class='jc'>{@link Tuple4} - Four-value tuple
081 *    <li class='jc'>{@link Tuple5} - Five-value tuple
082 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauCommons">juneau-commons</a>
083 * </ul>
084 *
085 * @param <A> The type of the value in this tuple.
086 */
087public class Tuple1<A> {
088
089   /**
090    * Creates a new tuple containing the specified value.
091    *
092    * <h5 class='section'>Example:</h5>
093    * <p class='bjava'>
094    *    Tuple1&lt;String&gt; <jv>tuple</jv> = Tuple1.<jsm>of</jsm>(<js>"value"</js>);
095    *    Tuple1&lt;String[]&gt; <jv>arrayTuple</jv> = Tuple1.<jsm>of</jsm>(<jk>new</jk> String[]{<js>"a"</js>, <js>"b"</js>});
096    * </p>
097    *
098    * @param <A> The value type.
099    * @param a The value to wrap in the tuple.  Can be <jk>null</jk>.
100    * @return A new tuple containing the specified value.
101    */
102   public static <A> Tuple1<A> of(A a) {
103      return new Tuple1<>(a);
104   }
105
106   private final A a;
107   private final int hashCode;
108
109   /**
110    * Constructor.
111    *
112    * @param a Object value.  Can be <jk>null</jk>.
113    */
114   public Tuple1(A a) {
115      this.a = a;
116      this.hashCode = h(a);
117   }
118
119   @Override /* Overridden from Object */
120   public boolean equals(Object o) {
121      return o instanceof Tuple1<?> o2 && eq(this, o2, (x, y) -> eq(x.a, y.a));
122   }
123
124   /**
125    * Returns the value contained in this tuple.
126    *
127    * <h5 class='section'>Example:</h5>
128    * <p class='bjava'>
129    *    Tuple1&lt;String&gt; <jv>tuple</jv> = Tuple1.<jsm>of</jsm>(<js>"hello"</js>);
130    *    String <jv>value</jv> = <jv>tuple</jv>.getA();  <jc>// Returns "hello"</jc>
131    * </p>
132    *
133    * @return The value contained in this tuple.
134    */
135   public A getA() { return a; }
136
137   /**
138    * Returns the value contained in this tuple wrapped in an {@link Optional}.
139    *
140    * <h5 class='section'>Example:</h5>
141    * <p class='bjava'>
142    *    Tuple1&lt;String&gt; <jv>tuple</jv> = Tuple1.<jsm>of</jsm>(<js>"hello"</js>);
143    *    Optional&lt;String&gt; <jv>value</jv> = <jv>tuple</jv>.optA();  <jc>// Returns Optional.of("hello")</jc>
144    *
145    *    Tuple1&lt;String&gt; <jv>tuple2</jv> = Tuple1.<jsm>of</jsm>(<jk>null</jk>);
146    *    Optional&lt;String&gt; <jv>value2</jv> = <jv>tuple2</jv>.optA();  <jc>// Returns Optional.empty()</jc>
147    * </p>
148    *
149    * @return The value wrapped in an Optional, or Optional.empty() if the value is null.
150    */
151   public Optional<A> optA() {
152      return o(a);
153   }
154
155   @Override /* Overridden from Object */
156   public int hashCode() {
157      return hashCode;
158   }
159}