2009-10-11 42 views
12

Tôi đã tự hỏi liệu có một cấu trúc dữ liệu hoạt động như một OberservableCollection gần giống như trong C# có khả năng lấy một kiểu nhất định hay không.Tương đương với C# ObservableCollection trong Java

ví dụ:

Trong C# i am có thể nói ..

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

Giả sử rằng Bia lớp được thực hiện và chúng ta có thể thay đổi nồng độ cồn để

Beer[1].content = 5; 

tôi đã tự hỏi nếu có ai biết nếu có một cấu trúc dữ liệu/s mà làm việc cũng như với Java.


Tôi là lập trình viên C#, không có nhiều lập trình viên Java nên chỉ cần tự hỏi. Ngoài ra, nó có thể có trong một loại tùy chỉnh, không phải chung chung.

+1

Tính năng chính của bộ sưu tập có thể quan sát là bạn có thể quan sát nó để thay đổi - tức là nhận sự kiện khi có bất kỳ nội dung nào trong danh sách được thêm/xóa. Có phải đó là những gì bạn cần ? – nos

Trả lời

5

org.apache.commons.events.observable Class ObservableCollection

+0

Xin lưu ý, thư viện sự kiện này không ổn định và không được phát triển tích cực vì nó nằm trong nhánh không hoạt động của các giao thức apache. Do đó bạn sẽ không tìm thấy bất kỳ bản phát hành nào của thư viện này. –

-1

Chắc chắn, bạn có thể làm điều này. Nếu bạn đã có một lớp được gọi là Soda, bạn có thể làm:

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

Sau đó, bạn có thể làm

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

Tại sao bạn sẽ sử dụng một ArrayList thay vì một Danh sách ? –

+2

Danh sách là giao diện, danh sách mảng thực hiện. Các thẻ chung không hiển thị các thẻ mã mà tôi vừa thêm. (Happy Snarfblam) – broschb

+8

Câu trả lời này không liên quan đến câu hỏi .... – msangel

2

Nếu bạn muốn quan sát danh sách của bạn, ví dụ: được thông báo khi có thay đổi danh sách, bạn có thể sử dụng Glazed Lists.

Nếu bạn chỉ muốn sửa đổi các đối tượng được lưu trữ trong danh sách của mình, bạn có thể lấy đối tượng của mình bằng cách sử dụng List.get(int index) hoặc bằng cách lặp lại danh sách.

Nếu bạn muốn tự động tạo đối tượng Bia khi lưu trữ chuỗi vào danh sách, có thể bạn sẽ cần phải viết trình bao bọc danh sách đơn giản của riêng bạn.

2

JavaFX hiện có ObservableList phù hợp với nhu cầu của bạn, trong trường hợp đó bạn don' t muốn phụ thuộc vào JavaFX - đây là một lớp mà tôi đã viết một lúc trước có thể được sử dụng thay thế.

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

cấu trúc dữ liệu quan sát được (ObservableList, ObservableMap, vv) có trong 7u6 Oracle Java + như một phần của dự án JavaFX. Thư viện tương ứng cho OpenJDK được cung cấp bởi dự án OpenJFX.

Đây là hướng dẫn về using JavaFX collections.

Và một số mẫu mã cho việc sử dụng một danh sách quan sát JavaFX từ các hướng dẫn liên kết:

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

Bạn có thể xem xét sử dụng java.util.Lớp có thể quan sát, dưới đây là ví dụ:

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

    } 
} 

Bằng cách này, mỗi lần ArrayList được truy cập, hai người quan sát được thông báo.

Các vấn đề liên quan