为什么听众列出了列表?

时间:2010-05-30 10:39:09

标签: java list listener

为什么监听器列表(例如在Java中使用addXxxListener()removeXxxListener()来注册和取消注册监听器)名为 lists ,并且通常实现为ListsSet不是更合适,因为在听众的情况下,

  • 无论他们被调用的顺序如何(尽管可能存在这样的需求,但他们是特殊情况;普通的监听器机制没有这样的保证),并且
  • 不需要多次注册同一个侦听器(无论是这样做会导致调用同一个侦听器1次还是N次,或者是错误,是另一个问题)

这只是一个传统问题吗?无论如何,套装都是引擎盖下的某种列表。是否存在性能差异?迭代List比迭代Set更快或更慢?要么采取更多或更少的记忆?差异肯定几乎可以忽略不计。

3 个答案:

答案 0 :(得分:9)

侦听器列表成为列表(而不是集合)的一个重要原因也解释了为什么您经常看到它们是向后迭代的。一个常见的场景涉及监听器在收到某些更改通知时将自身移除为监听器。如果侦听器存储为列表并向前迭代(或存储为集合并以某种未确定的顺序迭代),则将自身移除为侦听器将导致ConcurrentModificationException。

因此,将侦听器存储为列表并按向后顺序通知。然后,如果侦听器在通知时将其自身从侦听器列表中删除,则不会导致ConcurrentModificationException或移动其他尚未通知的侦听器的索引。

答案 1 :(得分:1)

什么样的套装?是否所有侦听器都实现了equals和hashCode以便使用哈希集,或者身份哈希集会这样做?将监听器添加到列表两次的用例是否值得复杂?是否有一种简单的机制可以使集合在调用其处理程序期间安全地阻止添加或删除侦听器?

可能存在一些性能差异,但肯定有更复杂的设计,它会强制多个添加多个删除决策进入库而不是将其留给应用程序。

答案 2 :(得分:0)

你完全正确。应将听众添加到集合中。如你所说,不止一次添加一个监听器是没有意义的。此外,如果您使用集合,则不会依赖于侦听器的顺序。这是最重要的事情:如果你认真对待软件开发并且我们发现每个原则都能引导我们更好地设计,那么一个人就不应该依赖它:隔离,独立,责任。

这里提到的每个方面(多线程,性能......)必须在第一个想法中从属于自己,但如果你有充分的理由可能会被打破。我的意思是非常好的原因。

顺便说一下:让听众自行删除是一种不好的做法。添加和删​​除应该是对称的。因此应该通过注册它的对象删除监听器。如果你有很多听众,你很快就会陷入困境。