Esiste un modo migliore per avere un listener su una raccolta java piuttosto che racchiuderlo in una classe che implementa il pattern observer?Un buon modo per avere un listener della collezione?
risposta
Si dovrebbe verificare Glazed Lists
Contiene classi List osservabili, quali eventi di fuoco ogni volta che vengono aggiunti elementi, rimossi, sostituiti, ecc
Bene, se in realtà non è necessaria un'istanza java.util.Collection o List, è possibile utilizzare uno DefaultListModel. Non sono a conoscenza di eventuali implementazioni di raccolte "reali" con supporto incorporato di listener/observer.
È collegato la versione di Java 6 di DefaultListModel, che non usa Generics. La [versione di Java 7] (http://docs.oracle.com/javase/7/docs/api/javax/swing/DefaultListModel.html), che potrebbe rendere il tuo suggerimento più attraente. –
@MartinRust bene, sì, la risposta è da 2 anni prima che uscisse Java 7. Se lo aggiornerò, potrei usare Java 8 ora –
"Commons-Events fornisce classi aggiuntive per eventi di accensione e gestione. Si concentra sul framework Java Collections, fornendo decoratori ad altre raccolte che generano eventi".
Dovrebbe essere notato che questo è ancora un progetto sandbox. Uno interessante comunque. – BalusC
È possibile utilizzare il ForwardingSet, ForwardingList, ecc, da Guava a decorare un'istanza particolare con il comportamento desiderato.
Ecco la mia implementazione che utilizza solo le API JDK pianura:
// create an abstract class that implements this interface with blank implementations
// that way, annonymous subclasses can observe only the events they care about
public interface CollectionObserver<E> {
public void beforeAdd(E o);
public void afterAdd(E o);
// other events to be observed ...
}
// this method would go in a utility class
public static <E> Collection<E> observedCollection(
final Collection<E> collection, final CollectionObserver<E> observer) {
return new Collection<E>() {
public boolean add(final E o) {
observer.beforeAdd(o);
boolean result = collection.add(o);
observer.afterAdd(o);
return result;
}
// ... generate rest of delegate methods in Eclipse
};
}
ci sono molti modi per raggiungere questo - spesso io uso questo approccio
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ObservableArrayList<E> extends ArrayList<E> {
private @interface MethodId {
private static final int REMOVE = 2;
private static final int ADD = 1;
}
public interface ListObserver<E> {
void onElementAdded(E element);
void onElementRemoved(E element);
}
public ObservableArrayList(int capacity) {
super(capacity);
ensureObserver();
}
public ObservableArrayList() {
ensureObserver();
}
public ObservableArrayList(Collection<? extends E> collection) {
super(collection);
ensureObserver();
}
private List<WeakReference<ListObserver<E>>> _listObserverWeakRefList;
public void addObserver(ListObserver<E> observer) {
_listObserverWeakRefList.add(new WeakReference<ListObserver<E>> (observer));
}
private void ensureObserver() {
if (_listObserverWeakRefList == null) {
_listObserverWeakRefList = new ArrayList<>();
}
}
@Override
public boolean add(E object) {
super.add(object);
callObservable(MethodId.ADD, object);
return true;
}
@Override
public boolean remove(Object object) {
boolean removed = super.remove(object);
if (removed) callObservable(MethodId.REMOVE, object);
return removed;
}
private void callObservable(@MethodId int methodId, Object element) {
for (WeakReference<ListObserver<E>> observerRef : _listObserverWeakRefList) {
ListObserver<E> observer = observerRef.get();
if (observer != null) {
switch (methodId) {
case MethodId.ADD:
observer.onElementAdded((E) element);
break;
case MethodId.REMOVE:
observer.onElementRemoved((E) element);
break;
}
}
}
}
}
- 1. Filter_var è un buon modo per andare?
- 2. È un buon modo per usare java.util.concurrent.FutureTask?
- 3. Qual è un buon modo per creare un progetto Backbone.js?
- 4. C'è un buon modo per copiare un widget Gtk?
- 5. Un buon modo per cancellare un vettore float?
- 6. qual è un buon modo per combinare attraverso un set?
- 7. C'è un buon modo per rilevare un attacco NFS stante
- 8. E 'regex un buon modo per testare un url
- 9. C'è un buon modo per mavenificare un gioco! applicazione quadro?
- 10. È un buon modo per intercettare le chiamate di sistema?
- 11. C'è un buon modo per rilevare che MySQL è "pronto?"
- 12. Un buon modo per generare proceduralmente un'immagine "blob" in 2D
- 13. C'è un modo per avere viste diverse in un NSCollectionView?
- 14. iPhone: c'è un modo per caricareFromNib e avere un riutilizzatoreIdentificatore?
- 15. Qual è un buon modo per distribuire un'applicazione Perl?
- 16. Qual è un buon modo per fornire ulteriori decorazioni/metadati per i parametri della funzione Python?
- 17. Un buon modo per visualizzare immagini di grandi dimensioni online
- 18. Un buon modo per implementare callback utilizzabili in C++
- 19. C'è un buon modo per analizzare il codice C# 3.0?
- 20. C'è un buon modo per convertire tra BitmapSource e Bitmap?
- 21. Un buon modo per convertire tra brevi e byte?
- 22. Un buon modo per eseguire il debug di nullPointerException
- 23. Qual è un buon modo per dividere le stringhe qui?
- 24. Un buon modo per generare GUID sul motore di app?
- 25. C'è un buon modo per gestire le eccezioni in Python?
- 26. È un buon modo per fare JS OOP?
- 27. Qual è un buon modo per documentare sub/pub?
- 28. C'è un modo per recuperare tutto il nome del campo della collezione in mongodb?
- 29. Qual è un buon modo per testare un file per vedere se è un file zip?
- 30. C'è un modo per avere paralleli per ogni ciclo?
concordato. GlazedLists è eccellente. – Barend
Infatti, uno o due delle stesse persone hanno lavorato su entrambi ... –
TransformationList di Liste glazed si aspetta che dispose() venga invocato manualmente invece di utilizzare WeakReferences per gli ascoltatori ....? 0.o Deve esserci qualcosa di meglio là fuori. – user515655