- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我关注从包含几千个元素的 Java PriorityQueue 创建排序数组的不同风格。 Java 8 docs说
If you need ordered traversal, consider using Arrays.sort(pq.toArray()).
但是,我确实喜欢流式 API,所以我最初拥有的是
Something[] elems = theHeap.stream().sorted(BY_CRITERION.reversed())
.toArray(Something[]::new);
(其中 BY_CRITERION
是 PriorityQueue 的自定义比较器,我确实想要它的相反顺序。)与以下相比,使用这个习惯用法有什么缺点吗:
Something[] elems = theHeap.toArray(new Something[0]);
Arrays.sort(elems, BY_CRITERION.reversed());
后一种代码显然更直接地遵循了 API 文档的建议,但除此之外,它是否真的在内存方面更有效率,例如分配的临时结构更少等?
我会认为流解决方案必须将流元素缓冲在一个临时结构(一个数组?)中,然后对它们进行排序,最后将排序后的元素复制到在toArray()
中分配的数组中。 .
而命令式解决方案会将堆元素缓冲到新分配的数组中,然后对它们进行排序。所以这可能少了一次复制操作。 (还有一个数组分配。Collection.toArray(new T[size])
与 Collection.toArray(new T[0])
的讨论在这里无关紧要。例如,请参阅 here 了解为什么在 OpenJDK 上后者更快。)
那么排序效率呢? Arrays.sort() 的文档说
Temporary storage requirements vary from a small constant for nearly sorted input arrays to n/2 object references for randomly ordered input arrays
同时 Stream.sorted()
的文档对这一点保持沉默。因此,至少在可靠记录方面,命令式解决方案似乎具有优势。
但是还有什么要知道的吗?
最佳答案
从根本上说,这两种变体的作用相同,并且由于它们都是库预期用例中的有效解决方案,因此在选择算法或添加优化方面,没有理由认为实现应该优先于另一种。
实际上,这意味着最昂贵的操作(排序)在内部以相同的实现方法结束。 sorted(…)
Stream 实现的操作将所有元素缓冲到一个中间数组中,然后调用 Arrays.sort(T[], int, int, Comparator<? super T>)
, 它将委托(delegate)给与方法 Arrays.sort(T[], Comparator<? super T>)
相同的方法您在第一个变体中使用,目标是内部 TimSort
中的排序方法类。
所有关于 Arrays.sort
的时间和空间复杂度的讨论适用于 Stream.sort
以及。但是虽然有性能差异。对于 Java 10 之前的 OpenJDK 实现,Stream 无法融合 sorted
与随后的 toArray
步骤,直接使用结果数组进行排序步骤。因此,目前,Stream 变体承担了从用于排序的中间数组到由传递给 toArray
的函数创建的最终数组的最终复制步骤。 .但是 future 的实现可能会学习这个技巧,那么,这两种解决方案之间的相关性能将完全不同。
关于java - 将 PriorityQueue 转换为排序数组的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51079032/
采用另一个优先级队列的 java API PriorityQueue 构造函数是否会破坏参数?如果是这样,它的clone()方法足以创建浅拷贝吗? 最佳答案 不,它不是破坏性的。几乎所有集合类都有复制
我正在尝试复制一个 PriorityQueue 对象。 我的目标是在不修改我原来的 PriorityQueue 的情况下更改我的 Copy 的某些对象 为了这样做,我复制了我的 PriorityQue
我正在解决leetcode的Merge K Sorted Lists problem . 使用 Python2 的 Queue 模块中的 PriorityQueue 的相同算法会为 Python3 的
当 PriorityQueue.size() > 0 在 Android 上时,当 PriorityQueue.peek() 返回 null 时,我遇到了问题。 我认为这可能是设备问题。有人有什么想法
我有一个asyncio.PriorityQueue,用作网络爬虫的URL队列,当我调用url_queue.get时,得分最低的URL首先从队列中删除()。当队列达到 maxsize 项时,默认行为是阻
完全二叉树 一棵深度为k的有n个结点的 二叉树 ,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与 满二叉树 中编号为i的结点在二叉树中的位置相同,则这棵
我很难理解 priorityqueue 如何使用 compareTo 方法对其内容进行排序。 我在上一门名为 Node.js 的类(class)。它有 4 个字段。 private char char
我目前有一种方法使用 scala.collection.mutable.PriorityQueue 按特定顺序组合元素。例如代码看起来有点像这样: def process[A : Ordering]
没有提供自定义比较器,优先级队列按升序插入元素,但是,在删除特定元素后,顺序会发生变化。 PriorityQueue pq = new PriorityQueue<>(); pq.add(10); p
这个问题已经有答案了: The built-in iterator for java's PriorityQueue does not traverse the data structure in a
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我指的是此博客上列出的代码:https://strstr.io/Leetcode1054-Distant-Barcodes/ 我在这里复制这段代码 class Solution { publi
这个问题已经有答案了: Why does PriorityQueue.toString return the wrong element order? [duplicate] (4 个回答) 已关闭
我有一个比较器类 NComparator,它比较 2 个 Node 对象并返回 1、-1 或 0。 我初始化了一个初始容量为 100 的 PriorityQueue 和那个 NComparator。
当项目是整数与字符串时,PriorityQueue 的不同行为让我非常困惑。但在解决这个问题之前,我想了解以下行为(使用项目作为整数)。 假设我有一个包含以下数据的优先级队列(对于每个元素,第一个值是
我有使用 PriorityQueue 的程序。 poll() 没有给出队列中的所有值。 class Coffee { public static void main(String[] args
所以我正在尝试构建我的第一个 prim 算法,为此我根据其权重按优先级对边缘进行排序。 所以我认为如果我使用优先级队列会很有帮助,为此我需要让我的边缘实现 Comparable<> 接口(interf
编译器(Java 8)提示以下代码没有合适的构造函数: PriorityQueue heap = new PriorityQueue((ListNode n1, ListNode n2) -> n1.
我有一个优先级队列,我在其中添加一个节点对象,其中节点应按它们包含的值排序。由于某种原因,优先级队列不会在添加时对节点进行排序。如果有人能发现其中的问题或有任何指导,我很感激。这是一个简短的示例: P
这是我在这里发表的第一篇文章,因此请随时为我指出关于在这里提出问题的正确方向。 我的问题出在 java.util.PriorityQueue 上。 我有一个初始化的队列; myComparab
我是一名优秀的程序员,十分优秀!