为什么JavaFX中没有ObservableQueues?

为什么JavaFX中没有ObservableQueue? 如果我们查看FXCollections的Java 9文档(只是为了查看是否有任何更改),我们会看到静态帮助器方法来创建Observable集,列表和映射。 还有一些方法可以创建Observable浮点数和整数数组。 但是,无法创建ObservableQueue。 Java中的Queue接口有许多有趣的实现,包括ArrayDeque,DelayQueue,ConcurrentLinkedQueue,PriorityQueue等。为什么不支持在JavaFX中创建ObservableQueues的原因是什么。

正如@TomasMikula在@ eckig(现已删除)答案中所评论的那样,对ObservableQueue需求可能不够。 如果您有一个可靠的用例,则应考虑提交function请求 。

与此同时,创建一个快速而肮脏的ObservableQueue实现Queue并通过inheritanceObservableListBase并包装Queue实现来添加“可观察性”并不难。 子类ObservableListBase是“快速”部分,但也是“脏”部分,因为您公开了List方法以及Queue方法; 因为任意Queue没有get(int index) ,实现它的唯一方法(我可以看到)是迭代到index 。 任何使用get迭代ObservableQueue ,将其视为List ,都将在O(n^2)时间内运行。 有了这个警告,以下应该可以很好地工作:

 import java.util.LinkedList; import java.util.Queue; import javafx.collections.ObservableListBase; public class ObservableQueue extends ObservableListBase implements Queue { private final Queue queue ; /** * Creates an ObservableQueue backed by the supplied Queue. * Note that manipulations of the underlying queue will not result * in notification to listeners. * * @param queue */ public ObservableQueue(Queue queue) { this.queue = queue ; } /** * Creates an ObservableQueue backed by a LinkedList. */ public ObservableQueue() { this(new LinkedList<>()); } @Override public boolean offer(E e) { beginChange(); boolean result = queue.offer(e); if (result) { nextAdd(queue.size()-1, queue.size()); } endChange(); return result ; } @Override public boolean add(E e) { beginChange() ; try { queue.add(e); nextAdd(queue.size()-1, queue.size()); return true ; } finally { endChange(); } } @Override public E remove() { beginChange(); try { E e = queue.remove(); nextRemove(0, e); return e; } finally { endChange(); } } @Override public E poll() { beginChange(); E e = queue.poll(); if (e != null) { nextRemove(0, e); } endChange(); return e ; } @Override public E element() { return queue.element(); } @Override public E peek() { return queue.peek(); } @Override public E get(int index) { Iterator iterator = queue.iterator(); for (int i = 0; i < index; i++) iterator.next(); return iterator.next(); } @Override public int size() { return queue.size(); } } 

您可以使用此注册ListChangeListener来通知对队列的修改。 (注意,如果你想支持提取器和更新通知,你需要做更多的工作......)。

 import javafx.collections.ListChangeListener.Change; public class ObservableQueueTest { public static void main(String[] args) { ObservableQueue oq = new ObservableQueue<>(); oq.addListener((Change change) -> { while (change.next()) { if (change.wasAdded()) { System.out.println("Added: "+change.getAddedSubList()); } if (change.wasRemoved()) { System.out.println("Removed: "+change.getRemoved()); } if (change.wasUpdated()) { System.out.println("Updated: "+oq.subList(change.getFrom(), change.getTo())); } if (change.wasReplaced()) { System.out.println("Replaced"); } } }); oq.offer("One"); oq.offer("Two"); oq.offer("Three"); System.out.println("Peek: "+oq.peek()); System.out.println("Remove..."); System.out.println(oq.remove()); System.out.println("Element:"); System.out.println(oq.element()); System.out.println("get(1): "+oq.get(1)); System.out.println("Poll: "); System.out.println(oq.poll()); System.out.println("Poll again:"); System.out.println(oq.poll()); System.out.println("Poll should return null:"); System.out.println(oq.poll()); System.out.println("Element should throw exception:"); System.out.println(oq.element()); } }