为什么 JavaFX 中没有 ObservableQueue?

2023-11-21

为什么JavaFX中没有ObservableQueue?如果我们查看 FXCollections 的 Java 9 文档(只是为了看看与 8 相比是否有任何更改),我们会看到用于创建 Observable 集、列表和映射的静态辅助方法。还有一些创建 Observable 浮点和整数数组的方法。但是,没有办法创建 ObservableQueue。 Java中的Queue接口有很多有趣的实现,包括ArrayDeque、DelayQueue、ConcurrentLinkedQueue、PriorityQueue等。JavaFX中不支持创建ObservableQueues的背后逻辑是什么。


正如 @TomasMikula 在 @eckig(现已删除)的回答中评论的那样,可能只是没有足够的需求ObservableQueue。如果您有可靠的用例,您应该考虑提交功能请求.

与此同时,创建一个快速而肮脏的方法并不难ObservableQueue实施Queue并通过子类化添加“可观察性”ObservableListBase并包裹一个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<E> extends ObservableListBase<E> implements Queue<E> {

    private final Queue<E> 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<E> 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<E> 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<String> oq = new ObservableQueue<>();
        oq.addListener((Change<? extends String> 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());
    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 JavaFX 中没有 ObservableQueue? 的相关文章

随机推荐

  • 覆盖风格和构建类型之外的应用程序 ID

    我有一个有多种口味的应用程序 A B C 和两种构建类型 debug release 在构建类型中debug我向应用程序 ID 添加后缀 如下所示 debug applicationIdSuffix debug 这对口味来说很好A and
  • 我应该使用什么 URL 来连接到 SVN 存储库?

    我安装了 TurtoiseSVN 和 ankhSVN 我在我的计算机上创建了一个存储库 C Documents and Settings user1 My Documents Subversion Repository 我正在尝试从同事的计
  • Surefire 重新运行失败的测试不起作用

    我想重新运行一个我知道会失败的测试 因为我正在尝试测试 Surefire 参数以重新运行失败的测试 我尝试使用这两个命令运行 Maven 但它们都没有按预期工作 Dsurefire rerunFailingTestsCount 2 Dtes
  • 上传文件时获取 API 和 multer 错误

    我正在尝试使用 fetch API 将文件上传到 node js 服务器 如果与此有关 我正在使用 github 的 pollyfill https github com github fetch 请求是这样完成的 const data n
  • keras AssertionError:类型“experimentalOptimizer”的重复注册

    我正在尝试为 CartPole v1 游戏构建深度 Q 学习代码 但是我遇到了断言错误 AssertionError Duplicate registrations for type experimentalOptimizer 一些堆栈跟踪
  • Select2 改变容器位置

    如何调整 Select2 容器的位置 以便搜索框位于原始选择元素的正上方 如本网站所示 http www jobnisit com en 在我看来 它在用户界面方面看起来更干净 诗 抱歉 我现在无法发布图片 有两种方法可以做到这一点 1 使
  • 将 Chrome 浏览器打包到 HTML5 Android 应用程序中

    我们正在开发几个基于 Sencha 框架的 HTML5 应用程序 并考虑将它们打包到 PhoneGap 等应用程序中 然而 即使你将这些打包到应用程序中 我假设你仍然需要处理 Android 碎片问题 因为各个制造商对浏览器进行了奇怪的修改
  • 应用程序在后台时 iPhone 手电筒不工作

    您好 我正在使用基于位置的应用程序 并且想要在后台使用 iPhone 相机手电筒 不幸的是 手电筒仅在前台工作 即使代码正在执行 它也会自动关闭后台的闪光灯 我使用的代码仅在前台运行 import
  • 创建交互式弹出对话框

    我想知道是否可以使用shiny 和shinyBS 创建一个交互式弹出对话框 例如 我有一个字符串 我想更改它 并且在执行之前会出现一个对话框 询问我是否真的要更改它 如果我说 是 它就会执行 否则它会放弃更改 这是我的尝试 但我发现了两个问
  • MongoError:拓扑已关闭,请连接

    我是一名前端开发人员 试图在新的 Next 项目中拓展自己的视野 第一次学习 Node Mongo 和 GraphQL 的服务器端 Apollo 对我来说是最简单的入门方式 因为我已经在之前的项目中使用过客户端 Apollo 我一直在关注官
  • 为什么我的 C 程序中出现 ws2_32.dll 的链接器错误?

    我正在 Visual Studio 2010 中编写我的程序 我无法链接名为ws2 32 dll和我的项目 谁能告诉我该怎么做 通常您不会链接到 ws2 32 dlldirectly而是 WS2 32 Lib 您可以在 Windows SD
  • StringBuilder 和 StringBuffer 的区别

    之间的主要区别是什么StringBuffer and StringBuilder 在决定其中任何一项时是否存在任何性能问题 StringBuffer是同步的 StringBuilder is not
  • Android xml布局中的视图限制是多少

    任何人都知道在 android 布局 XML 中 可以嵌入到 XML 中的最大视图限制是多少 有限制吗 严格来说 限制 是80 当布局中有太多视图时 Lint 会报告以下内容 AndroidLintTooManyViews 描述 布局有太多
  • 从当前光标位置创建范围 Word 2010 VBA

    我有一个 docm带有用户表单的文档 在用户表单上 我有一个按钮 需要在文档中最后一个已知的光标位置插入一些内容 一些文本 用于启动 为此 我想创建一个范围 我怎样才能获得这个范围的起始位置 Selection是文档中的当前位置 Selec
  • 如何将 UIScrollView 嵌套在 UIScrollView 中,以便用户可以滚动内部 UIScrollView?

    我还没有尝试过 但我假设一旦我知道用户想要在子滚动视图中滚动 我就必须禁用父滚动视图的滚动 对吧 两个滚动视图都是水平滚动的 如何暂时禁用父级的滚动检测 或者还有其他办法吗 UIScrollView 有一个属性叫做scrollEnabled
  • 在 Bootstrap 4 的较小屏幕上隐藏一列[重复]

    这个问题在这里已经有答案了 这是 Bootstrap 4 总是让我感到困惑的一个领域 假设你有这样的布局 div class container fluid div class row div class col sm 3 col sm 3
  • 不使用递归如何抛出堆栈溢出异常?

    不使用递归如何抛出堆栈溢出异常 由于没有其他人提到过 throw new System StackOverflowException 您可以在测试或进行故障注入时执行此操作
  • VS 插件将光标下的标识符的完整类型名称复制到剪贴板中[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 是否有一个 Visual Studio 插件可以将光标下的标识符的完整类型名称复制到剪贴板中 请不要将我链接到 VS 2010 复制类 接口的完整类
  • 如何从一个具有依赖性的批处理文件启动多个批处理文件?

    我想运行一个批处理文件 启动其他批处理文件 我看了这里发布的类似问题 如何在一个 BAT 文件中运行多个 BAT 文件 我按照这个例子 特别是最后一个建议 并且它起作用了 部分 它确实启动了我需要的批处理文件 但是 为了使应用程序正常运行
  • 为什么 JavaFX 中没有 ObservableQueue?

    为什么JavaFX中没有ObservableQueue 如果我们查看 FXCollections 的 Java 9 文档 只是为了看看与 8 相比是否有任何更改 我们会看到用于创建 Observable 集 列表和映射的静态辅助方法 还有一