Skip to content

Instantly share code, notes, and snippets.

@jqno jqno/SchoolTest.java
Created Feb 14, 2013

Embed
What would you like to do?
My answer to Cedric Beust's coding challenge ("Light" edition) http://beust.com/weblog/2013/02/13/coding-challenge-light-edition/
// My implementation of Cedric Beust's coding challenge:
//
// A School has either a name (“Stanford”) or a nickname (“UCSD”) or both.
//
// Your task is to write equals() and hashCode() methods for the School class
// that satisfy the following requirement: two Schools are identical if they
// either have the same name or the same nickname.
//
// http://beust.com/weblog/2013/02/13/coding-challenge-light-edition/
import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.Test;
public class SchoolTest {
public static final class School {
private final String name;
private final String nickname;
public School(String name, String nickname) {
this.name = name;
this.nickname = nickname;
}
// OK, let's give this equals method a try.
@Override
public boolean equals(Object obj) {
if (!(obj instanceof School)) {
return false;
}
School other = (School)obj;
return nullSafeEqual(name, other.name) ||
nullSafeEqual(nickname, other.nickname);
}
private boolean nullSafeEqual(String a, String b) {
return a == null ? b == null : a.equals(b);
}
@Override
public int hashCode() {
// Well, this *does* satisfy the hashCode contract, doesn't it :)?
return 42;
}
@Override
public String toString() {
return "School: name=" + name + ", nickname=" + nickname;
}
}
@Test
public void testEquals() {
// My alma mater:
School tue = new School("Technische Universiteit Eindhoven", "TU/e");
// There's a university in my home town that famously changed its name:
School one = new School("Katholieke Universiteit Brabant", "KUB");
School two = new School("Katholieke Universiteit Brabant", "UvT");
School three = new School("Universiteit van Tilburg", "KUB");
School four = new School("Universiteit van Tilburg", "UvT");
// Using EqualsVerifier to check equality.
// Full disclosure: it's written by me.
// See http://code.google.com/p/equalsverifier/
// It works for any pair of schools:
EqualsVerifier.forRelaxedEqualExamples(one, two)
.andUnequalExample(tue)
.verify();
EqualsVerifier.forRelaxedEqualExamples(three, four)
.andUnequalExample(tue)
.verify();
EqualsVerifier.forRelaxedEqualExamples(one, three)
.andUnequalExample(tue)
.verify();
EqualsVerifier.forRelaxedEqualExamples(two, four)
.andUnequalExample(tue)
.verify();
// But once you add a third school, it breaks down:
EqualsVerifier.forRelaxedEqualExamples(one, two, three)
.andUnequalExample(tue)
.verify();
// And that makes sense, because the transitivity requirement cannot hold:
// * one equals two
// * two equals three
// * one does not equal three
// Therefore, there is no way to write this equals method, and still satisfy
// the requirements of the equals contract.
// P.S. If I'm wrong, please let me know, so I can update EqualsVerifier :).
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.