001package basics.immutabledata;
002final public class Pair<S extends Comparable<S>, T extends Comparable<T>>
003implements Comparable<Pair<S,T>>
004{
005        final private S x;
006        final private T y;
007        public Pair(S x, T y) {
008                if (x == null || y == null)
009                        throw new IllegalArgumentException();
010                this.x = x;
011                this.y = y;
012        }
013        public S first() { return x; }
014        public T second() { return y; }
015        public String toString() { return "Pair(" + x + "," + y + ")"; }
016        public boolean equals(Object thatObject) {
017                if (thatObject == null)
018                        return false;
019                if (this == thatObject)
020                        return true;
021                // equals should not throw ClassCastException
022                if (!(this.getClass().equals(thatObject.getClass())))
023                        return false;
024                @SuppressWarnings("unchecked")
025                Pair<S,T> that = (Pair<S,T>) thatObject;
026                return x.equals(that.x)
027                                && y.equals(that.y);
028        }
029        private int hcode;
030        public int hashCode() {
031                if (hcode == 0) {
032                        hcode = 17;
033                        hcode = 37*hcode + x.hashCode();
034                        hcode = 37*hcode + y.hashCode();
035                }
036                return hcode;
037        }
038        public int compareTo(Pair<S,T> that) {
039                // compareTo may throw ClassCastException
040                int ix = x.compareTo(that.x);
041                if (ix != 0)
042                        return ix;
043                return y.compareTo(that.y);
044        }
045}