ObserverList extends ConcurrentModificationList<Observer<T>> { public void notifyObservers(T value) { try { updating = true; int size = data.size(); int i = 0; while (i < size) { Observer<T> e = data.get(i); if (e != null) { e.onChanged(value); } ++i; } } finally { updating = false; int i = data.size() - 1; while (removedCount > 0 && i >= 0) { if (data.get(i) == null) { data.remove(i); removedCount -= 1; } --i; } } } ObserverList();  ObserverList(int capacity); void notifyObservers(T value);  }
@Test public void TestNotifyObservers() { Observer<String> a = Callback("a"); Observer<String> b = Callback("b"); Observer<String> c = Callback("c"); ObserverList<String> list = concurrentListOf(a, b, c); assertEquals(3, list.size()); assertFalse(list.isEmpty()); list.notifyObservers("1"); assertResults("a:1", "b:1", "c:1"); list.notifyObservers("2"); assertResults("a:2", "b:2", "c:2"); }
@Test public void TestAdd() { ObserverList<String> list = concurrentListOf(); assertEquals(0, list.size()); assertTrue(list.isEmpty()); list.notifyObservers("1"); assertResults(); list.add(Callback("a")); assertEquals(1, list.size()); assertFalse(list.isEmpty()); list.notifyObservers("2"); assertResults("a:2"); list.add(Callback("b")); assertEquals(2, list.size()); assertFalse(list.isEmpty()); list.notifyObservers("3"); assertResults("a:3", "b:3"); list.add(Callback("c")); assertEquals(3, list.size()); assertFalse(list.isEmpty()); list.notifyObservers("4"); assertResults("a:4", "b:4", "c:4"); }
@Test public void TestRemove() { Observer<String> a = Callback("a"); Observer<String> b = Callback("b"); Observer<String> c = Callback("c"); ObserverList<String> list = concurrentListOf(a, b, c); list.remove(b); assertEquals(2, list.size()); assertFalse(list.isEmpty()); list.notifyObservers("1"); assertResults("a:1", "c:1"); list.remove(a); assertEquals(1, list.size()); assertFalse(list.isEmpty()); list.notifyObservers("2"); assertResults("c:2"); list.remove(a); assertEquals(1, list.size()); assertFalse(list.isEmpty()); list.notifyObservers("3"); assertResults("c:3"); list.remove(c); assertEquals(0, list.size()); assertTrue(list.isEmpty()); list.notifyObservers("3"); assertResults(); }
@Test public void TestRemoveWhileNotifying() { final ObserverList<String> list = concurrentListOf(); final Observer<String> a = Callback("a"); final Observer<String> c = Callback("c"); Observer<String> b = Callback("b", new Observer<String>() { @Override public void onChanged(String value) { list.remove(a); list.remove(c); } }); list.add(a); list.add(b); list.add(c); list.notifyObservers("1"); assertResults("a:1", "b:1"); assertEquals(1, list.size()); assertFalse(list.isEmpty()); list.notifyObservers("2"); assertResults("b:2"); }
@Test public void TestClearWhileNotifying() { final ObserverList<String> list = concurrentListOf(); Observer<String> a = Callback("a"); Observer<String> c = Callback("c"); Observer<String> b = Callback("b", new Observer<String>() { @Override public void onChanged(String value) { list.clear(); } }); list.add(a); list.add(b); list.add(c); list.notifyObservers("1"); assertResults("a:1", "b:1"); assertEquals(0, list.size()); assertTrue(list.isEmpty()); list.notifyObservers("2"); assertResults(); }