Correct (and best) collection type for listeners in Java

1.3k Views Asked by At

I just want to introduce a small observer pattern (listeners) in one of my classes, and I want to use the best-practice approach.

My listener interface:

public interface ExpansionListener {
    void expanded();
    void collapsed();
}

Therefore, I want to keep a list of listeners

private List listener; // What kind of list should I take?

and two methods addListener(ExpansionListener l) and removeListener(ExpansionListener l).

Now, my question: What kind of list should I take? I thought about using a concurrent list like CopyOnWriteArrayList, but I found out that also EventListenerList exists. What is the best-practice approach for listener-lists in Java?

1

There are 1 best solutions below

1
On BEST ANSWER

The CopyOnWriteArrayList is thread safe. Not all Swing components are thread safe.

Note: before Java 8, iterating over this collection would create garbage, however in Java 8 the Iterator can be placed on the stack with Escape Analysis.

final List<EventListener> listeners = new CopyOnWriteArrayList<>();

if (!listeners.contains(listener))
     listeners.add(listener);

Using a Set would be preferable esp as you might want to ignore duplicate registrations of a listener in a thread safe manner.

final Set<EventListener> listeners = new CopyOnWriteArraySet<>();

listeners.add(listener);

The performance will be much the same, though the CopyOnWriteArraySet has the advantage that the add is atomic, where as doing contains and then add is not atomic.

EDIT: As @Hulk suggests you could use CopyOnWriteArrayList.addIfAbsent, however this method is not available on List.

final CopyOnWriteArrayList<EventListener> listeners = new CopyOnWriteArrayList<>();

listeners.addIfAbsent(listener);