Is there a better way to have a listener on a java collection than wrap it in a class implementing the observer pattern ?
there are many ways to achieve this - often i use this approach
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ObservableArrayList extends ArrayList {
private @interface MethodId {
private static final int REMOVE = 2;
private static final int ADD = 1;
}
public interface ListObserver {
void onElementAdded(E element);
void onElementRemoved(E element);
}
public ObservableArrayList(int capacity) {
super(capacity);
ensureObserver();
}
public ObservableArrayList() {
ensureObserver();
}
public ObservableArrayList(Collection extends E> collection) {
super(collection);
ensureObserver();
}
private List>> _listObserverWeakRefList;
public void addObserver(ListObserver observer) {
_listObserverWeakRefList.add(new WeakReference> (observer));
}
private void ensureObserver() {
if (_listObserverWeakRefList == null) {
_listObserverWeakRefList = new ArrayList<>();
}
}
@Override
public boolean add(E object) {
super.add(object);
callObservable(MethodId.ADD, object);
return true;
}
@Override
public boolean remove(Object object) {
boolean removed = super.remove(object);
if (removed) callObservable(MethodId.REMOVE, object);
return removed;
}
private void callObservable(@MethodId int methodId, Object element) {
for (WeakReference> observerRef : _listObserverWeakRefList) {
ListObserver observer = observerRef.get();
if (observer != null) {
switch (methodId) {
case MethodId.ADD:
observer.onElementAdded((E) element);
break;
case MethodId.REMOVE:
observer.onElementRemoved((E) element);
break;
}
}
}
}
}