2009-10-11 9 views
12

Ich frage mich, ob es eine Datenstruktur gibt, die wie eine OberservableCollection wirkt, fast wie in C#, die einen bestimmten Typ annehmen kann.Äquivalent von C# ObservableCollection in Java

ex:

In C# ich in der Lage bin zu sagen ..

ObservableCollection<Beer> Beer = new ObservableCollection<Beer>(); 
Beer.add("Bud"); <br> 
Beer.add("Coors"); 

Unter der Annahme, dass die Klasse Bier hergestellt wird, und wir können den Alkoholgehalt, dass

Beer[1].content = 5; 

ich so ändern Ich frage mich, ob jemand weiß, ob es eine solche Datenstruktur gibt, die auch mit Java funktioniert.


Ich bin ein C# -Programmierer, nicht viel von einem Java-Programmierer so nur wundernd. Außerdem muss es in der Lage sein, einen benutzerdefinierten Typ aufzunehmen, nicht generisch.

+1

Das Hauptmerkmal der beobachtbaren Sammlung ist, dass Sie es für Änderungen beobachten können - d. H. Ereignisse erhalten, wenn etwas in der Liste hinzugefügt/entfernt wird. Ist das was du brauchst? – nos

Antwort

5

org.apache.commons.events.observable Class ObservableCollection

+0

Bitte beachten Sie, dass diese Ereignisbibliothek nicht stabil ist und nicht aktiv entwickelt wird, wie es im ruhenden Zweig von Apache Commons ist. Daher werden Sie keine Release-Builds dieser Bibliothek finden. –

-1

Sicher, Sie können dies tun. Wenn Sie eine Klasse namens Soda hatte, die Sie tun können:

List<Soda> sodas = new ArrayList<Soda>(); 
sodas.add(new Soda("Coke")); 
sodas.add(new Soda("Sprite")); 

Dann könnten Sie

sodas.get(1).setSugar(255); 
+0

Warum würden Sie eine ArrayList anstelle einer Liste verwenden? –

+2

Liste ist die Schnittstelle, Arraylist die Implementierung. Die generischen Tags wurden nicht mit den Code-Tags angezeigt, die ich gerade hinzugefügt habe. (Happy Snarfblam) – broschb

+8

Diese Antwort bezieht sich nicht auf Frage .... – msangel

2

tun, wenn Sie Ihre Listen beachten wollen, das heißt benachrichtigt werden, wenn die Liste ändert, können Sie Glazed Lists verwenden.

Wenn Sie nur Objekte in Ihren Listen ändern möchten, können Sie Ihre Objekte mithilfe von List.get(int index) oder durch Iterieren der Liste abrufen.

Wenn Sie beim Speichern von Strings in der Liste automatisch Beer-Objekte erstellen möchten, müssen Sie wahrscheinlich einen eigenen einfachen Listenwrapper schreiben.

2

JavaFX hat jetzt ObservableList die Ihren Anforderungen entsprechen, die Sie im Fall don‘ Ich möchte mich auf JavaFX verlassen - hier ist eine Klasse, die ich vor einiger Zeit geschrieben habe und die stattdessen verwendet werden kann.

import java.util.Arrays; 
import java.util.Collection; 
import java.util.Iterator; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.ListIterator; 

/** 
* 
* @author bennyl 
*/ 
public class ObservableList<T> implements List<T> { 

    private List<T> wrapped; 
    private LinkedList<Listener<T>> listeners = new LinkedList<>(); 

    public ObservableList(List wrapped) { 
     this.wrapped = wrapped; 
    } 

    public void addListener(Listener l) { 
     listeners.add(l); 
    } 

    public void removeListener(Listener l) { 
     listeners.remove(l); 
    } 

    @Override 
    public int size() { 
     return wrapped.size(); 
    } 

    @Override 
    public boolean isEmpty() { 
     return wrapped.isEmpty(); 
    } 

    @Override 
    public boolean contains(Object o) { 
     return wrapped.contains(o); 
    } 

    @Override 
    public Iterator<T> iterator() { 
     final Iterator<T> iterator = wrapped.iterator(); 
     return new Iterator<T>() { 
      T current = null; 

      @Override 
      public boolean hasNext() { 
       return iterator.hasNext(); 
      } 

      @Override 
      public T next() { 
       return current = iterator.next(); 
      } 

      @Override 
      public void remove() { 
       iterator.remove(); 
       fireRemoved(current); 
      } 
     }; 
    } 

    private void fireRemoved(T... items) { 
     fireRemoved(Arrays.asList(items)); 
    } 

    @Override 
    public Object[] toArray() { 
     return wrapped.toArray(); 
    } 

    @Override 
    public <T> T[] toArray(T[] a) { 
     return wrapped.toArray(a); 
    } 

    @Override 
    public boolean add(T e) { 
     if (wrapped.add(e)) { 
      fireAdded(e); 
      return true; 
     } else { 
      return false; 
     } 
    } 

    @Override 
    public boolean remove(Object o) { 
     if (wrapped.remove(o)) { 
      fireRemoved((T) o); 
      return true; 
     } 

     return false; 
    } 

    @Override 
    public boolean containsAll(Collection<?> c) { 
     return wrapped.containsAll(c); 
    } 

    @Override 
    public boolean addAll(Collection<? extends T> c) { 
     if (wrapped.addAll(c)) { 
      fireAdded(c); 
      return true; 
     } 

     return false; 
    } 

    @Override 
    public boolean addAll(int index, Collection<? extends T> c) { 
     if (wrapped.addAll(index, c)) { 
      fireAdded(c); 
     } 

     return false; 
    } 

    @Override 
    public boolean removeAll(Collection<?> c) { 
     if (wrapped.removeAll(c)) { 
      fireRemoved((Collection<? extends T>) c); 
      return true; 
     } 

     return false; 
    } 

    @Override 
    public boolean retainAll(Collection<?> c) { 
     if (wrapped.retainAll(c)) { 
      fireStracturalChange(); 
     } 

     return false; 
    } 

    @Override 
    public void clear() { 
     wrapped.clear(); 
     fireStracturalChange(); 
    } 

    @Override 
    public boolean equals(Object o) { 
     return wrapped.equals(o); 
    } 

    @Override 
    public int hashCode() { 
     return wrapped.hashCode(); 
    } 

    @Override 
    public T get(int index) { 
     return wrapped.get(index); 
    } 

    @Override 
    public T set(int index, T element) { 
     T old = wrapped.set(index, element); 
     fireRemoved(old); 
     fireAdded(element); 
     return old; 
    } 

    @Override 
    public void add(int index, T element) { 
     wrapped.add(index, element); 
     fireAdded(element); 
    } 

    @Override 
    public T remove(int index) { 
     T old = wrapped.remove(index); 
     fireRemoved(old); 
     return old; 
    } 

    @Override 
    public int indexOf(Object o) { 
     return wrapped.indexOf(o); 
    } 

    @Override 
    public int lastIndexOf(Object o) { 
     return wrapped.lastIndexOf(o); 
    } 

    @Override 
    public ListIterator<T> listIterator() { 
     return wrapped.listIterator(); 
    } 

    @Override 
    public ListIterator<T> listIterator(int index) { 
     return wrapped.listIterator(index); 
    } 

    @Override 
    public List<T> subList(int fromIndex, int toIndex) { 
     return wrapped.subList(fromIndex, toIndex); 
    } 

    private void fireRemoved(Collection<? extends T> asList) { 
     for (Listener<T> l : listeners) { 
      l.onItemsRemoved(this, asList); 
     } 
    } 

    private void fireAdded(T... e) { 
     fireAdded(Arrays.asList(e)); 
    } 

    private void fireAdded(Collection<? extends T> asList) { 
     for (Listener<T> l : listeners) { 
      l.onItemsAdded(this, asList); 
     } 
    } 

    private void fireStracturalChange() { 
     for (Listener<T> l : listeners) { 
      l.onStracturalChange(this); 
     } 
    } 

    public static interface Listener<T> { 

     void onItemsAdded(ObservableList<T> source, Collection<? extends T> items); 

     void onItemsRemoved(ObservableList<T> source, Collection<? extends T> items); 

     void onStracturalChange(ObservableList<T> source); 
    } 
} 
3

beobachtbare Datenstrukturen (ObservableList, ObservableMap, usw.) sind in Oracle Java 7u6 enthalten + als Teil des JavaFX Projekts. Eine entsprechende Bibliothek für OpenJDK wird vom Projekt OpenJFX zur Verfügung gestellt.

Hier ist ein Tutorial auf using JavaFX collections.

Und einige Beispielcode eine JavaFX beobachtbaren Liste aus dem verknüpften Tutorial für die Nutzung:

import java.util.List; 
import java.util.ArrayList; 
import javafx.collections.*; 

public class CollectionsDemo { 
    public static void main(String[] args) { 
    // Use Java Collections to create the List. 
    List<String> list = new ArrayList<String>(); 

    // Now add observability by wrapping it with ObservableList. 
    ObservableList<String> observableList = FXCollections.observableList(list); 
    observableList.addListener(new ListChangeListener() { 
     @Override public void onChanged(ListChangeListener.Change change) { 
     System.out.println("Detected a change! "); 
     } 
    }); 

    // Changes to the observableList WILL be reported. 
    // This line will print out "Detected a change!" 
    observableList.add("item one"); 

    // Changes to the underlying list will NOT be reported 
    // Nothing will be printed as a result of the next line. 
    list.add("item two"); 

    System.out.println("Size: "+observableList.size()); 
    } 
} 
0

können Sie betrachten die java.util verwenden.Beobachtbaren Klasse, hier ist ein Beispiel:

public class Try extends Observable{ 

    private static List<String> list = new ArrayList<String>(); 
    private static Try observableObj = new Try(); 

    public static List<String> getList(){ 
    observableObj.setChanged(); 
    observableObj.notifyObservers(); 
    return list; 
    } 


    public static void main(String[] args) throws RemoteException { 

    Try2 observer1 = new Try2(); 
    Try2 observer2 = new Try2(); 
    observableObj.addObserver(observer1); 
    observableObj.addObserver(observer2); 

    System.out.println(getList().isEmpty()); 

    } 
} 

class Try2 implements Observer{ 

    @Override 
    public void update(Observable arg0, Object arg1) { 
    System.out.println(this.toString()+" has been notified"); 

    } 
} 

Auf diese Weise jedes Mal, wenn die Arraylist die beiden Beobachter zugegriffen wird benachrichtigt,.