当前位置: 首页 > 面试题库 >

在显示进度的同时对大型集合进行排序

常雪风
2023-03-14
问题内容

更新进度条时对集合排序的最佳方法是什么?目前,我有这样的代码

for (int i = 0; i < items.size(); i++)
{
    progressBar.setValue(i);

    // Uses Collections.binarySearch:
    CollectionUtils.insertInOrder(sortedItems, item.get(i));
}

这显示进度,但是进度条随着项目数量的sortedItems增加而减慢。有谁有更好的方法?理想情况下,我想使用类似于的接口,Collections.sort()以便尝试不同的排序算法。

任何帮助将是巨大的!

作为背景,这段代码正在从Lucene撤回许多文档(1到1000万个),并在它们之上运行自定义比较器。通过将数据写回到磁盘上对它们进行排序将太慢而无法实用。大部分成本是从磁盘上读取项目,然后在项目上运行比较器。我的电脑有大量的内存,因此没有与交换到磁盘等有关的问题。

最后,我选择了Stephen的解决方案,因为它非常干净,使我可以轻松添加多线程排序算法。


问题答案:

您在这里要小心。您已选择使用一种算法来增量构建排序的数据结构,以便(我接受)您可以显示进度条。但是,这样做时,您选择的排序方法 可能
比最佳排序慢得多。(两种类型都可以,O(NlogN)但是性能要比big-O行为更多…)

如果您担心这可能是个问题,请比较使用TreeMap和对典型集合进行排序的时间Collections.sort。后者的工作方式是将输入集合复制到数组中,对数组进行排序,然后再将其复制回。(它的工作原理最好的,如果在输入集合是一个ArrayList,如果你不需要结果作为可变集合就可以避免使用最终拷贝过来的Collection.toArrayArrays.sortArrays.asList代替。)

一种替代方法是使用Comparator对象,该对象跟踪被调用的次数,并使用该对象跟踪排序的进度。您可以利用以下事实:比较器通常会被粗略调用N*log(N),尽管您可能需要根据实际使用的算法1对其进行校准。

顺便说一下,与对插入次数进行计数相比,对比较器的调用进行计数可以更好地指示进度。当您接近完成排序时,您将不会看到进度出现放缓的趋势。

(您将拥有不同的线程来读取和写入计数器,因此您需要考虑同步。声明计数器volatile可以正常工作,但会增加内存流量。如果您对进度条感到满意,也可以忽略该问题有时会显示过时的值…具体取决于您的平台等)

1-这有问题。在某些算法中,比较次数可能会根据要排序的数据的初始顺序而急剧变化。对于这种算法,没有办法校准将在“非平均”情况下工作的计数器。



 类似资料:
  • 问题内容: 更新进度条时对集合排序的最佳方法是什么?目前,我有这样的代码: 这显示进度,但是进度条随着项目数量的增加而减慢。有谁有更好的方法?理想情况下,我想使用类似于的接口,以便尝试不同的排序算法。 任何帮助将是巨大的! 作为背景,这段代码正在从Lucene撤回许多文档(1到1000万个),并在它们之上运行自定义比较器。通过将数据写回到磁盘上对它们进行排序将太慢而无法实用。大部分成本是从磁盘上读

  • 我试图写一个函数来排序一个对象集合。由于对象都是相同的类型(相同的用户定义类),因此它们的属性集是相同的。是否有可能(通过代码)发现对象的属性,以便将集合放在一个二维数组中,每行代表一个对象,每列代表它的一个属性? 另一种解决方案是将集合中的每个对象复制到对象数组中,并根据它们的一个属性对它们进行排序,该属性的名称作为字符串传递给函数。但是我不知道如何使用作为字符串传递的属性名来指向对象的属性。

  • 本文向大家介绍JAVA对list集合进行排序Collections.sort(),包括了JAVA对list集合进行排序Collections.sort()的使用技巧和注意事项,需要的朋友参考一下 对一个集合中的对象进行排序,根据对象的某个指标的大小进行升序或降序排序。代码如下: 进行降序排列 进行升序排列 经过测试发现,只需要把两个对象的位置调换一下即可升序或降序。 如果指标相同,根据多个指标进行

  • 问题内容: 假设我有两个类CLassA和CLassB。它们有一个共同的属性,例如每个类拥有的元素数量。 我如何从ClassA和CLassB的对象创建一个集合,并按该属性排序(降序升序无所谓)? 我收集了一个类型,但是当我尝试实现Comparable Interface时,我无法使用该方法(例如,获取返回元素nr的get)。 我有什么解决方案? 谢谢你的帮助! 问题答案: 实际上,如果要将它们放在同

  • 问题内容: 我有一堂课,有两个日期字段说: 我想根据日期对上述类别的列表进行排序,如果它们相等,则根据max(activation)和max(timeStamp)进行排序。 我尝试的代码如下所示,仅获取max(激活) 任何帮助将不胜感激。 谢谢 问题答案: 这样就可以了!

  • 问题内容: 在我正在使用的代码下面,可以正常工作并输出名称,但不能使用sort方法。我期望“ Collections.sort(nameFromText);” 按名字的字母顺序对ArrayList进行排序。 我究竟做错了什么? 问题答案: 方法期望要排序的列表元素具有可比性。元素类型应该实现接口,或者您应该使用带有通用实例的重载方法。 在下面的代码中,您不满足上述两个条件。您的类既没有实现,也没有