Relaxed equality

Sometimes, simply comparing all the values of the fields is not the best way to define equals. The famous example of this is rational numbers, where 1/2 and 2/4 are equal, even though they have different fields. EqualsVerifier calls this ‘relaxed equality’.

The best way to explain how to deal with this, is by showing an example. Let’s say you have a Rational class:

class Rational {
    private final int numerator;
    private final int denominator;

    public equals(Object obj) {
        if (!(obj instanceof Rational)) {
            return false;
        }
        Rational other = (Rational)obj;
        return (numerator / denominator) == (other.numerator / other.denominator);
                              // awfully bad implementation but you get the idea
    }

    // leaving out everything else for brevity
}

Then you can write your test like this:

@Test
public void testEquality() {
    Rational a = new Rational(1, 2);
    Rational b = new Rational(2, 4);
    Rational x = new Rational(1, 3);
    EqualsVerifier.forRelaxedEqualExamples(a, b)
        .andUnequalExample(x)
        .verify();
}

As you can see, you have to give EqualsVerifier some example objects for your class. First, you have to give at least two examples that are equal to each other, but that have different values for their fields. In this case, we give the 1/2 and 2/4 from our example above. You can give more than two examples, if you need to.

Second, you should give an example that’s unequal to the objects you gave before. In this case, we give 1/3. You can give more than one example, if you need to. EqualsVerifier does the obvious sanity checks: no duplications are allowed.

That’s all there is to it!

Updated: