public class Ficha implements Comparable<Ficha> {
    private int a, b;
    public static Ficha DOBLE_BLANCA = new Ficha(0,0);
    public static int NUM_MAX = 6;
    Ficha(int a, int b) {
        this.a = a;
        this.b = b;
    }
    int getA() {
        return a;
    }
    int getB() {
        return b;
    }
    public Ficha girarFicha() {
        int aux = this.a;
        this.a = this.b;
        this.b = aux;
        return this;
    }
    public boolean esUnDoble() {
        return (a == b);
    }
    public int pesoPonderado() {
        // Si tenemos un metodo de pesoPonderado()
        // los 3 siguientes pueden ser siempre igual. :-)
        if (a > b) {
            return a * NUM_MAX + b;
        } else {
            return b * NUM_MAX + a;
        }
    }
    // compareTo() es el unico metodo que MUST ser implementado
    // para la interface comparable<>
    @Override
    public int compareTo(Ficha other) {
        return (this.pesoPonderado() - other.pesoPonderado());
    }
    // Pero... equals() debe ser coherente con compareTo()
    // Si no se sobreescribe, se usa el equals() de Object que es ==
    @Override
    public boolean equals(Object obj) {
        // Version pro
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Ficha other = (Ficha) obj;
        /*
        if (this.a != other.a) return false;
        if (this.b != other.b) return false;
        return true;
        */
        return (this.compareTo(other) == 0);
        // Porque 3:2| equals 2:3|
    }
    // A class that overrides equals must also override hashCode.
    // Puede que no los distribuya uniformemente,
    // pero al menos es coherente con los dos anteriores.
    @Override
    public int hashCode() {
        return this.compareTo(DOBLE_BLANCA);
    }
    @Override
    public String toString() {
        return (a + ":" + b + "|");
    }
}
