EquivalenceFinder { public void markEquivalent(T one, T two) { ArgumentValidation.notNull("first arg", one); ArgumentValidation.notNull("second arg", two); if (one.equals(two)) return; equivalences.put(one, two); equivalences.put(two, one); } EquivalenceFinder();   EquivalenceFinder(int maxTraversals); void copyEquivalences(EquivalenceFinder<? extends T> source); void markEquivalent(T one, T two); boolean areEquivalent(T one, T two); Set<T> findEquivalents(T node); Set<Entry<T, T>> equivalencePairs(); Set<T> findParticipants(); @Override String toString();  }
@Test public void simple() { EquivalenceFinder<Integer> finder = create(); finder.markEquivalent(1, 2); check(finder, true, 1, 2); }
@Test public void transitive() { EquivalenceFinder<Integer> finder = create(); finder.markEquivalent(1, 2); finder.markEquivalent(2, 3); check(finder, true, 1, 2); check(finder, true, 1, 3); check(finder, true, 2, 3); }
@Test public void transitiveBushy() { EquivalenceFinder<Integer> finder = create(); finder.markEquivalent(1, 2); finder.markEquivalent(2, 3); finder.markEquivalent(2, 4); finder.markEquivalent(2, 5); finder.markEquivalent(5, 6); check(finder, true, 1, 6); }
@Test public void loopedOneApart() { EquivalenceFinder<Integer> finder = create(); finder.markEquivalent(1, 2); finder.markEquivalent(2, 1); check(finder, true, 1, 2); }
@Test public void loopedTwoApart() { EquivalenceFinder<Integer> finder = create(); finder.markEquivalent(1, 2); finder.markEquivalent(2, 3); finder.markEquivalent(3, 1); check(finder, true, 1, 2); check(finder, true, 1, 3); check(finder, true, 2, 3); }
@Test public void traverseBarelyWorks() { EquivalenceFinder<Integer> finder = create(6); finder.markEquivalent(1, 2); finder.markEquivalent(2, 3); finder.markEquivalent(3, 4); finder.markEquivalent(4, 5); finder.markEquivalent(5, 6); check(finder, true, 1, 6); }
@Test public void traverseBarelyFails() { EquivalenceFinder<Integer> finder = create(4); finder.markEquivalent(1, 2); finder.markEquivalent(2, 3); finder.markEquivalent(3, 4); finder.markEquivalent(4, 5); finder.markEquivalent(5, 6); check(finder, null, 1, 6); }
@Test public void noneEquivalenceSet() { EquivalenceFinder<Integer> finder = create(); finder.markEquivalent(2, 3); checkEquivalents(1, finder); }
@Test public void someEquivalenceSet() { EquivalenceFinder<Integer> finder = create(); finder.markEquivalent(1, 2); finder.markEquivalent(2, 3); checkEquivalents(1, finder, 2, 3); }
@Test public void loopedEquivalenceSet() { EquivalenceFinder<Integer> finder = create(); finder.markEquivalent(1, 2); finder.markEquivalent(2, 3); finder.markEquivalent(3, 1); checkEquivalents(1, finder, 2, 3); }
@Test(expected = IllegalArgumentException.class) public void nullEquivalence() { create().markEquivalent(1, null); }