Java 中听众的正确(和最佳)集合类型

Correct (and best) collection type for listeners in Java

我只想在我的 类 中引入一个小的观察者模式(监听器),我想使用最佳实践方法。

我的监听器接口:

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

因此,我想保留一个听众列表

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

和两种方法addListener(ExpansionListener l)removeListener(ExpansionListener l)

现在,我的问题:我应该拿什么样的清单?我考虑过使用像 CopyOnWriteArrayList, but I found out that also EventListenerList 这样的并发列表。 Java 中监听器列表的最佳实践方法是什么?

CopyOnWriteArrayList 是线程安全的。并非所有 Swing 组件都是线程安全的。

注意:在 Java 8 之前,迭代此集合会产生垃圾,但是在 Java 8 中,Iterator 可以通过逃逸分析放置在堆栈上。

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

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

最好使用 Set,尤其是因为您可能希望以线程安全的方式忽略侦听器的重复注册。

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

listeners.add(listener);

性能将大致相同,尽管 CopyOnWriteArraySet 的优点是 add 是原子的,而 contains 然后 add 不是原子的。

编辑:@Hulk 建议您可以使用 CopyOnWriteArrayList.addIfAbsent,但是此方法在 List 上不可用。

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

listeners.addIfAbsent(listener);