从百万条记录中获得前10名和后10名

时间:2015-05-11 16:33:26

标签: java binary-tree binary-search-tree priority-queue

我有一份显示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)
    }

如果我也可以使用其他一些数据结构,请告诉我。

由于

3 个答案:

答案 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)

excel电子表格中有40亿条记录?不,你没有https://superuser.com/questions/366468/what-is-the-maximum-allowed-rows-in-a-microsoft-excel-xls-or-xlsx

您应该在数据库上执行此操作,而不是依赖于Java实现。对于这么多记录,它的效率必然低于优化的数据库查询。