Ternary { @Override public boolean equals(Object obj) { if (!(obj instanceof Ternary)) { return false; } Ternary<?, ?, ?> that = (Ternary<?, ?, ?>)obj; return (t != null ? t.equals(that.t) : that.t == null) && (u != null ? u.equals(that.u) : that.u == null) && (v != null ? v.equals(that.v) : that.v == null); } Ternary(T t, U u, V v); T first(); void first(T t); U second(); void second(U u); V third(); void third(V v); @Override // Note: This means any two pairs with null for both values will match each // other but what can I do? This is due to stupid type erasure. int hashCode(); @Override boolean equals(Object obj); @Override String toString();  }
@Test public void testEquals() { Assert.assertEquals(new Ternary<String, String, String>("a", "b", "c"), new Ternary<String, String, String>("a", "b", "c")); Assert.assertFalse(new Ternary<String, String, String>("a", "b", "c").equals(new Ternary<String, String, String>("a", "b", "d"))); Assert.assertFalse(new Ternary<String, String, String>("a", "b", "c").equals("")); Assert.assertFalse(new Ternary<String, String, String>("a", "b", "c").equals(null)); Assert.assertFalse(new Ternary<String, String, String>("a", "b", "c").equals(new Pair<String, String>("a", "b"))); }