Java中C#ObservableCollection的等价物

我想知道是否有一个像OberservableCollection一样的数据结构,就像在C#中能够采用某种类型一样。

例如:

在C#我可以说..

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

假设制造啤酒类,我们可以改变酒精含量

  Beer[1].content = 5; 

我想知道是否有人知道是否有这样的数据结构与Java一起工作。


我是一名C#程序员,不是很多Java程序员,所以只是想知道。 此外,它必须能够采用自定义类型,而不是通用类型。

org.apache.commons.events.observable 类ObservableCollection

可观察的数据结构( ObservableList , ObservableMap等)作为JavaFX项目的一部分包含在Oracle Java 7u6 +中。 OpenJFX项目提供了OpenJDK的相应库。

这是一个使用JavaFX集合的教程。

以及一些使用链接教程中的JavaFX可观察列表的示例代码:

 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 list = new ArrayList(); // Now add observability by wrapping it with ObservableList. ObservableList 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()); } } 

如果您想观察列表,即在列表更改时收到通知,您可以使用Glazed Lists 。

如果您只想修改列表中存储的对象,可以使用List.get(int index)或迭代列表来获取对象。

如果要在将字符串存储到列表中时自动创建Beer对象,则可能需要编写自己的简单列表包装器。

JavaFX现在具有符合您需求的ObservableList,在您不想依赖JavaFX的情况下 – 这是我之前写过的可以替代使用的类。

 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 implements List { private List wrapped; private LinkedList> 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 iterator() { final Iterator iterator = wrapped.iterator(); return new Iterator() { 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[] 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 c) { if (wrapped.addAll(c)) { fireAdded(c); return true; } return false; } @Override public boolean addAll(int index, Collection c) { if (wrapped.addAll(index, c)) { fireAdded(c); } return false; } @Override public boolean removeAll(Collection c) { if (wrapped.removeAll(c)) { fireRemoved((Collection) 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 listIterator() { return wrapped.listIterator(); } @Override public ListIterator listIterator(int index) { return wrapped.listIterator(index); } @Override public List subList(int fromIndex, int toIndex) { return wrapped.subList(fromIndex, toIndex); } private void fireRemoved(Collection asList) { for (Listener l : listeners) { l.onItemsRemoved(this, asList); } } private void fireAdded(T... e) { fireAdded(Arrays.asList(e)); } private void fireAdded(Collection asList) { for (Listener l : listeners) { l.onItemsAdded(this, asList); } } private void fireStracturalChange() { for (Listener l : listeners) { l.onStracturalChange(this); } } public static interface Listener { void onItemsAdded(ObservableList source, Collection items); void onItemsRemoved(ObservableList source, Collection items); void onStracturalChange(ObservableList source); } } 

Java Collections api中至少没有

http://download-llnw.oracle.com/javase/1.5.0/docs/guide/collections/designfaq.html#27

您可以创建包装器或代理

您可以考虑使用java.util.Observable类,这是一个示例:

 public class Try extends Observable{ private static List list = new ArrayList(); private static Try observableObj = new Try(); public static List 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"); } } 

这样,每次访问ArrayList时,都会通知两个观察者。

当然,你可以做到这一点。 如果你有一个名为Soda的课程,你可以这样做:

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

然后你可以做到

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