001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.tools;
003import java.util.Objects;
004
005/**
006 * A pair of objects.
007 * @param <A> Type of first item
008 * @param <B> Type of second item
009 * @since 429
010 */
011public final class Pair<A, B> {
012
013    /**
014     * The first item
015     */
016    public A a;
017
018    /**
019     * The second item
020     */
021    public B b;
022
023    /**
024     * Constructs a new {@code Pair}.
025     * @param a The first item
026     * @param b The second item
027     */
028    public Pair(A a, B b) {
029        this.a = a;
030        this.b = b;
031    }
032
033    @Override
034    public int hashCode() {
035        return Objects.hash(a, b);
036    }
037
038    @Override
039    public boolean equals(Object other) {
040        if (this == other) return true;
041        if (other == null || getClass() != other.getClass()) return false;
042        Pair<?, ?> pair = (Pair<?, ?>) other;
043        return Objects.equals(a, pair.a) &&
044               Objects.equals(b, pair.b);
045    }
046
047    /**
048     * Sorts a single-typed pair so {@code a <= b}.
049     * @param <T> type of both elements
050     * @param p pair
051     * @return {@code p}
052     */
053    public static <T> Pair<T, T> sort(Pair<T, T> p) {
054        if (p.b.hashCode() < p.a.hashCode()) {
055            T tmp = p.a;
056            p.a = p.b;
057            p.b = tmp;
058        }
059        return p;
060    }
061
062    @Override
063    public String toString() {
064        return "<" + a + ',' + b + '>';
065    }
066
067    /**
068     * Convenient constructor method
069     * @param <U> type of first item
070     * @param <V> type of second item
071     * @param u The first item
072     * @param v The second item
073     * @return The newly created Pair(u,v)
074     */
075    public static <U, V> Pair<U, V> create(U u, V v) {
076        return new Pair<>(u, v);
077    }
078}