2016-04-12 3 views
11

Ich möchte nur ein kleines Beobachtermuster (Listener) in einer meiner Klassen einführen, und ich möchte den Best-Practice-Ansatz verwenden.Korrekter (und bester) Sammlungstyp für Listener in Java

Meine Zuhörer Schnittstelle:

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

Deshalb möchte ich

eine Liste der Zuhörer halten
private List listener; // What kind of list should I take? 

und zwei Methoden addListener(ExpansionListener l) und removeListener(ExpansionListener l).

Jetzt, meine Frage: Welche Art von Liste sollte ich nehmen? Ich dachte über eine gleichzeitige Liste wie CopyOnWriteArrayList, aber ich fand heraus, dass auch EventListenerList existiert. Was ist der Best-Practice-Ansatz für Listener-Listen in Java?

+0

eventListenerList scheint – Sanjeev

+2

ein guter Kandidat zu sein, ich 'Liste verwenden würde ' für einen Start, wenn Sie diese Art von Zuhörer zulassen möchten. Dann würde ich wahrscheinlich mit "CopyOnWriteArrayList" gehen, da Änderungen an den Listenern wahrscheinlich recht selten sind, aber Schreibvorgänge parallel von mehreren Threads ausgeführt werden können (nur Annahmen über Ihre Architektur). – Thomas

+0

Ein 'Set' ist besser geeignet, um zu verhindern, dass ein Objekt mehrere Listener desselben Typs hat. – Titus

Antwort

9

Die CopyOnWriteArrayList ist threadsicher. Nicht alle Swing-Komponenten sind Thread-sicher.

Hinweis: Vor Java 8 würde die Iteration über diese Sammlung Müll verursachen. In Java 8 kann die Iterator jedoch mit Escape Analysis auf dem Stapel platziert werden.

Die Verwendung eines Sets wäre vorzuziehen, insbesondere wenn Sie doppelte Registrierungen eines Hörers auf thread-sichere Weise ignorieren möchten.

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

listeners.add(listener); 

wird die Leistung sehr ähnlich sein, obwohl die CopyOnWriteArraySet den Vorteil hat, dass die add atomar ist, wo als contains und dann add ist nicht atomar zu tun.

BEARBEITEN: Wie @Hulk vorschlägt, könnten Sie CopyOnWriteArrayList.addIfAbsent verwenden, diese Methode ist jedoch nicht in der Liste verfügbar.

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

listeners.addIfAbsent(listener); 
+0

@Hulk wäre es für 'CopyOnWriteArrayList', obwohl es nicht auf' List' verfügbar ist –