我有一份显示2-4百万条记录的报告。我从oracle获取记录到java并将其推送到excel报告。这一切都已经完成了!
现在,我还需要添加一个包含前10个和后10个记录的新选项卡。最好的方法是什么?
我应该在java中使用PriorityQueue实现还是使用二叉树来跟踪前10名和后10名。我不需要在数据结构中存储十亿条记录。我只需要一次保存10个。 例如:
PriorityQueue<DataObject> queueTop10 = new PriorityQueue<DataObject>(10, topComparator);
PriorityQueue<DataObject> queueLast10 = new PriorityQueue<DataObject>(10, leastComparator);
while (data is coming from database)
{
// push to excel stuff here
queueTop10 .add(dataObject); OR binarytreeTop.insert(dataObject)
queueLast10.add(dataObject); OR binarytreeLeast.insert(dataObject)
}
如果我也可以使用其他一些数据结构,请告诉我。
由于
答案 0 :(得分:2)
热门命中算法使用最小堆(Java中为PriorityQueue
),但算法中应该有一些大小检查。假设每个项目都有一个分数,并且您想要收集分数最高的10个项目。 PriorityQueue
有效地使用最低分数公开项目:
PriorityQueue<DataObject> top = new PriorityQueue(10, comparator);
for (DataObject item : items) {
if (top.size() < 10) top.add(item);
else if(comparator.compare(top.peek(), item) < 0) {
top.remove();
top.add(item);
}
}
答案 1 :(得分:0)
PriorityQueue<T>
将无法按原样使用您的代码,因为构造函数中的10是初始容量;你的队列将随着时间的推移增长到1B项。
然而,TreeSet<T>
只会进行一些修改。每次队列增长超过10时,您需要添加删除第11项的代码:
TreeSet<DataObject> top10 = new TreeSet<DataObject>(topComparator);
TreeSet<DataObject> bottom10 = new TreeSet<DataObject>(leastComparator);
while (data is coming from database) {
top10.add(dataObject);
if (top10.size() == 11) {
top10.pollLast();
}
bottom10.add(dataObject);
if (bottom10.size() == 11) {
bottom10.pollLast();
}
}
答案 2 :(得分:0)
您应该在数据库上执行此操作,而不是依赖于Java实现。对于这么多记录,它的效率必然低于优化的数据库查询。