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);
我只想在我的 类 中引入一个小的观察者模式(监听器),我想使用最佳实践方法。
我的监听器接口:
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);