How to implement equals for generic pairs?

2019-04-12 09:56发布

问题:

Just for fun, I'm trying to implement a generic Pair class in Java. I'm having trouble with equals:

public class Pair<A, B>
{
    public final A _1;
    public final B _2;

    // ... unnecessary details left out ...

    public boolean equals(Pair<A, B> that)
    {
        return (_1.equals(that._1)) && (_2.equals(that._2));
    }

    @Override
    public boolean equals(Object o)
    {
        return (o instanceof Pair<A, B>) && equals((Pair<A, B>) o);
    }
}

However, o instanceof Pair<A, B> does not seem to work. Why is that?

Using (o instanceof Pair) && equals((Pair<A, B>) o) gives me a warning for the cast. Getting rid of the <A, B> part on the cast still gives me a warning, which I guess also some sense.

Does that mean Java cannot prevent clients from comparing Pairs with different type arguments?

回答1:

Does that mean Java cannot prevent clients from comparing Pairs with different type arguments?

Yes, but that's the point -- equals should work with any arbitrary object. What you want would look like

@Override
public boolean equals(Object o)
{
    if (o instanceof Pair) {
       Pair<?, ?> pair = (Pair<?, ?>) o;
       return _1.equals(pair._1) && _2.equals(pair._2);
    }
    return false;
}

But this should be fine, as long as A and B have proper implementations of equals that take arbitrary Objects.



回答2:

You can not use instanceof like you do due to type erasure. You can only check for instanceof Pair.
Also what is up with that _1 and _2? Really?



回答3:

o instanceof Pair<A, B> 

does not work because generics are not there at runtime, therefore instanceof is not aware of them.