2009-10-11 30 views
12

Me preguntaba si hay una estructura de datos que actúe como una OberservableCollection casi como en C# que puede tomar un cierto tipo.Equivalente a C# ObservableCollection en Java

ejemplo:

En C# Soy capaz de decir ..

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

Suponiendo que la cerveza de clase se hace y que puede cambiar el contenido de alcohol de manera que

Beer[1].content = 5; 

I Me preguntaba si alguien sabe si existe una estructura de datos que funcione tan bien con Java.


Soy un programador de C#, no mucho de un programador de Java, así que me pregunto. Además, debe poder tomar un tipo personalizado, no genérico.

+1

La característica principal de la colección observable es que puede observarla para detectar cambios, es decir, obtener eventos cuando cualquier elemento de la lista se agrega o elimina. Es eso lo que necesita ? – nos

Respuesta

5

org.apache.commons.events.observable Class ObservableCollection

+0

Tenga en cuenta que esta biblioteca de eventos no es estable y no se desarrolla activamente, ya que se encuentra en la rama inactiva de apache commons. Por lo tanto, no encontrará ninguna versión de lanzamiento de esta biblioteca. –

-1

Claro, usted puede hacer esto. Si usted tenía una clase llamada Soda, que podría hacer:

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

entonces usted podría hacer

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

¿Por qué utilizaría una lista de matrices en lugar de una lista ? –

+2

Lista es la interfaz, arraylist la implementación. Las etiquetas genéricas no se muestran sin las etiquetas de código que acabo de agregar. (Snarfblam feliz) – broschb

+8

Esta respuesta no está relacionada con la pregunta .... – msangel

2

Si desea observar sus listas, es decir, recibir una notificación cuando los cambios de la lista, se puede utilizar Glazed Lists.

Si solo desea modificar objetos almacenados en sus listas, puede obtener sus objetos usando List.get(int index), o al iterar la lista.

Si desea crear automáticamente objetos Beer al almacenar cadenas en la lista, es probable que necesite escribir su propio contenedor de lista simple.

2

JavaFX tiene ahora ObservableList que coincidan con sus necesidades, en el caso de que usted don' Quiero depender de JavaFX: esta es una clase que escribí hace un tiempo y que puede usarse en su lugar.

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

estructuras de datos observables (ObservableList, ObservableMap, etc) están incluidos en 7u6 Oracle Java + como parte del proyecto JavaFX. El proyecto OpenJFX proporciona una biblioteca correspondiente para OpenJDK.

Aquí hay un tutorial en using JavaFX collections.

Y un código de ejemplo para el uso de una lista observables JavaFX desde el tutorial vinculado:

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

Usted puede considerar el uso de la java.util.clase observable, aquí está un ejemplo:

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

    } 
} 

De esta manera, cada vez que el ArrayList se accede a los dos observadores Informarte.