2009-10-11 16 views
12

Zastanawiam się, czy istnieje struktura danych, która działa jak OberservableCollection prawie jak w C#, który jest w stanie przyjąć określony typ.Równoważnik C# ObservableCollection w Javie

ex:

W języku C# jestem w stanie powiedzieć ..

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

Zakładając, że piwo klasa jest wykonany i możemy zmienić zawartość alkoholu tak, że

Beer[1].content = 5; 

I zastanawiałem się, czy ktoś wie, czy istnieje taka struktura danych, która również działa z Javą.


Jestem programistą C#, nie bardzo programistą Java, więc po prostu się zastanawiam. Musi również być w stanie przyjąć typ niestandardowy, a nie ogólny.

+1

Główną cechą obserwowalnej kolekcji jest to, że można ją zaobserwować w celu wprowadzenia zmian - tzn. Uzyskać zdarzenia, gdy cokolwiek na liście zostanie dodane/usunięte. Czy to jest to, czego potrzebujesz? – nos

Odpowiedz

5

org.apache.commons.events.observable Class ObservableCollection

+0

Należy pamiętać, że ta biblioteka wydarzeń nie jest stabilna i nie jest aktywnie rozwijana, tak jak jest w nieaktywnej gałęzi wspólnoty Apache. Dlatego nie znajdziesz żadnych wersji kompilacji tej biblioteki. –

-1

Oczywiście, można to zrobić. Jeśli miał klasę o nazwie Soda, można zrobić:

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

Następnie można zrobić

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

Dlaczego miałbyś używać ArrayList zamiast listy ? –

+2

Lista jest interfejsem, tablica lista implementacji. Ogólne znaczniki nie pokazały w/out tagów kodu, które właśnie dodałem. (Happy Snarfblam) – broschb

+8

Ta odpowiedź nie jest związana z pytaniem .... – msangel

2

jeśli chcesz obserwować swoje listy, to znaczy być powiadamiany o zmianach na liście, można użyć Glazed Lists.

Jeśli chcesz tylko zmodyfikować obiekty przechowywane na twoich listach, możesz uzyskać obiekty za pomocą List.get(int index) lub przez iterowanie listy.

Jeśli chcesz automatycznie tworzyć obiekty Beer podczas zapisywania Ciągów na liście, prawdopodobnie będziesz musiał napisać własną prostą owijkę.

2

JavaFX ma teraz ObservableList, które odpowiadają Twoim potrzebom, w przypadku, don” t zależy od JavaFX - tutaj jest klasa, którą napisałem jakiś czas temu, która może być użyta zamiast tego.

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

Obserwacje struktury danych (ObservableList, ObservableMap, etc) są zawarte w 7u6 Oracle Java + w ramach projektu JavaFX. Odpowiednią bibliotekę dla OpenJDK zapewnia projekt OpenJFX.

Oto poradnik na temat using JavaFX collections.

A niektóre przykładowy kod do zaobserwowania przy użyciu listy JavaFX z połączonego tutorialu:

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

Można rozważyć użycie java.util.Obserwowalne klasa, oto przykład:

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"); 

    } 
} 

W ten sposób za każdym razem dostaje ArrayList obejrzano dwóch obserwatorów otrzymywać powiadomienia.