001package com.identityworksllc.iiq.common;
002
003import java.io.Serializable;
004import java.util.Objects;
005import java.util.StringJoiner;
006
007/**
008 * A group of four items
009 *
010 * @param <A> The first item type
011 * @param <B> The second item type
012 * @param <C> The third item type
013 * @param <D> The fourth item type
014 */
015public class Quad<A, B, C, D> implements Serializable {
016    /**
017     * Constructs a new quad tuple of the four items given
018     *
019     * @param first The first time
020     * @param second The second item
021     * @param third The third item
022     * @param fourth The fourth item
023     *
024     * @param <X> The first item type
025     * @param <Y> The second item type
026     * @param <Z> The third item type
027     * @param <Q> The fourth item type
028     *
029     * @return A typed Quad containing those three items
030     */
031    public static <X, Y, Z, Q> Quad<X, Y, Z, Q> of(X first, Y second, Z third, Q fourth) {
032        return new Quad<>(first, second, third, fourth);
033    }
034
035    /**
036     * The first item in the quad
037     */
038    private final A first;
039    /**
040     * The fourth item in the quad
041     */
042    private final D fourth;
043    /**
044     * The second item in the quad
045     */
046    private final B second;
047    /**
048     * The third item in the quad
049     */
050    private final C third;
051
052    /**
053     * Creates a new Quad of the four given items
054     */
055    private Quad(A a, B b, C c, D d) {
056        this.first = a;
057        this.second = b;
058        this.third = c;
059        this.fourth = d;
060    }
061
062    @Override
063    public boolean equals(Object o) {
064        if (this == o) return true;
065        if (o == null || getClass() != o.getClass()) return false;
066        Quad<?, ?, ?, ?> quad = (Quad<?, ?, ?, ?>) o;
067        return Objects.equals(first, quad.first) && Objects.equals(second, quad.second) && Objects.equals(third, quad.third) && Objects.equals(fourth, quad.fourth);
068    }
069
070    /**
071     * Gets the first item in the quad
072     * @return The first item
073     */
074    public A getFirst() {
075        return first;
076    }
077
078    /**
079     * Gets the fourth item in the quad
080     * @return The fourth item
081     */
082    public D getFourth() {
083        return fourth;
084    }
085
086    /**
087     * Gets the second item in the quad
088     * @return The second item
089     */
090    public B getSecond() {
091        return second;
092    }
093
094    /**
095     * Gets the third item in the quad
096     * @return The third item
097     */
098    public C getThird() {
099        return third;
100    }
101
102    @Override
103    public int hashCode() {
104        return Objects.hash(first, second, third, fourth);
105    }
106
107    @Override
108    public String toString() {
109        return new StringJoiner(", ", Quad.class.getSimpleName() + "[", "]")
110                .add("first=" + first)
111                .add("second=" + second)
112                .add("third=" + third)
113                .add("fourth=" + fourth)
114                .toString();
115    }
116}