How can you represent two equal enum constants as not being equal when semantically different?
<p>I'm currently working on a tic-tac-toe game, and I keep track of the cells' values using a <code>State</code> enum.</p>

<pre><code>protected static enum State {
    BLANK, X, O;

    @Override
    public String toString() {
        if (this.name().equals("BLANK"))
            return " ";
        else
            return this.name();
    }

    @Override
    public boolean equals(Object o2) {
        if (this == o2)
            return true;

        if (!(o2 instanceof State))
            return false;

        State state2 = (State)o2;
        if (state2.name().equals("BLANK"))
            return false;

        return this.name().equals(state2.name());
    }
};
</code></pre>

<p>A winner can then be determined if the necessary cells are equal. The issue is, if the cell is <code>BLANK</code>, "BLANK" will win. My original thought was to override it with what I have above, but this creates a compile error because apparently <code>boolean equals(Object)</code> is final in an enum (I understand it's because of <a href="https://stackoverflow.com/questions/2964704/why-java-does-not-allow-overriding-equalsobject-in-an-enum">this article</a>). So, my next thought was to just overload it as follows:</p>

<pre><code>public boolean equals(State state2) {
    if (state2.name().equals("BLANK"))
        return false;

    return this.name().equals(state2.name());
}
</code></pre>

<p>But we know <a href="https://stackoverflow.com/questions/12787947/overriding-object-equals-vs-overloading-it">this won't work all the time</a>, because some things like Collections will only look at the <code>equals(Object)</code> signature. The issue here is that, semantically, a blank cell doesn't exist at all; there's nothing there, so there should be nothing to compare against to be equal to another blank cell. Another similar example would be if I had an enum for numbers: <code>enum Sign { Positive, Negative, NaN }</code>. An efficient way of multiplying the two numbers and finding the resulting sign would be (pretending of course the computer didn't already handle signs) would be:</p>

<pre><code>if (this.sign.equals(number2.sign))
    sign = Sign.Positive;
else
    sign = Sign.Negative;
</code></pre>

<p>Undefined numbers can't share a sign because they're undefined! You can always inelegantly check to see later if the sign is undefined and change stuff at that point, but that seems very backwards and inefficient, because it's still had to check equality and do a lot of work already in vain. The number example kind of falls apart where it can just be made to equal NaN, but my point is that really isn't accurate, and I'm sure there are plenty of other instances where two enum constants wouldn't semantically be equal and wouldn't work like that, such as in my tic-tac-toe example. Is there an elegant way of handling these kinds of situations in Java?</p>