在 Java 中,我有一个 SortedSet,它可能有 100,000 个元素。我想高效优雅地获取最后 25 个元素。我有点疑惑。
为了获得前25 个元素,我将迭代并在 25 个元素之后停止。但我不知道如何以相反的顺序迭代。有任何想法吗?
SortedSet<Integer> summaries = getSortedSet();
// what goes here :-(
你需要一个NavigableSet
. 否则,您将不得不低效地进行操作,遍历整个SortedSet
元素并将元素收集到一个Queue
您一直修剪为 25 个元素的元素中。
SortedSet<T>
的设计假设一个非常简单的迭代模型,仅向前,因此找到前 n 个条目很容易,但找到最后一个将需要通过迭代器进行昂贵的读取,以维护最后 n 个条目的窗口。
在 1.6 中添加的NavigableSet<T>
解决了这个问题(并且 1.4 TreeSet 中唯一的 SortedSet 实现实现了它,因此它很可能成为您的替代品)。
NavigableSet<T> set = new TreeSet<T>();
// add elements
set.descendingIterator() // iterate over the last n entires as needed
反转您的排序并获取前 25 个项目。然后,您可以将那些将是有效的,因为它只有 25 个项目。
布鲁斯
不同的数据结构将更适合此操作。
这不是一种优雅的方式或非常有效的方式,但假设 SortedSet 是按升序排列的,您可以获得 Last() 项并将其删除,将其存储在另一个列表中,然后重复 25 次。然后,您将不得不再次将这些元素放回去!
将 Set 放入 List 并使用 subList()。我不确定创建列表的性能如何,因此您必须运行一些测试。不过,它肯定会使编码变得容易。
List f = new ArrayList( summaries);
List lastTwentyFive = f.subList( summaries.size() - 25, summaries.size() );
https://github.com/geniot/indexed-tree-map
您可能想看看IndexedTreeMap in indexed-tree-map
使用exact(size-25) 无需迭代即可到达索引处的元素。
我假设这在您的项目中不太可能有任何实际用途,但值得注意的是,您可能只是能够将列表按相反方向排序:)