views:

71

answers:

1

Why are listener lists (e.g. in Java those that use addXxxListener() and removeXxxListener() to register and unregister listeners) called lists, and usually implemented as Lists? Wouldn't a Set be a better fit, since in the case of listeners there's

  • No matter in which order they get called (although there may well be such needs, but they're special cases; ordinary listener mechanisms make no such guarantees), and
  • No need to register the same listener more than once (whether doing that should result in calling the same listener 1 times or N times, or be an error, is another question)

Is it just a matter of tradition? Sets are some kind of lists under the hood anyway. Are there performance differences? Is iterating through a List faster or slower than iterating through a Set? Does either take more or less memory? The differences are certainly almost negligible.

+1  A: 

What kind of set? Should all listeners implement equals and hashCode so that a hash set is used, or would an identity hash set do? Is the use case of adding a listener to a list twice worth the complexity? Is there as simple a mechanism for making the set safe against adding or removing listeners during calls to their handlers?

There might be some performance differences, but there certainly are more complicated design, and it forces the multiple add-multiple remove decision into the library rather than leaving it to the application.

Pete Kirkham
I think an identity hash set would be appropriate. But granted, there's no "CopyOnWriteIdentityHashSet" available out of the box, so using the common list idiom may be just simpler in achieving correct end result.
Joonas Pulakka
But: there indeed is a CopyOnWriteArraySet in Java 6, which is thread-safe ("Traversal via iterators is fast and cannot encounter interference from other threads."). According to http://java.sun.com/javase/6/docs/technotes/guides/collections/changes5.html "This implementation is well-suited to maintaining event-handler lists that must prevent duplicates."
Joonas Pulakka
@Joonas Since the Swing handlers are called in the Swing thread, the issue was always modifying the underlying collection and invalidating the iterator rather than concurrent updates. But if you did want those semantics, you certainly could use a copy-on-write set.
Pete Kirkham
That's the cool thing with CopyOnWriteXXX: Modifying the underlying collection does *not* invalidate the iterator.
Joonas Pulakka