从一百万条记录中获取前 10 名和后 10 名
Get top 10 and last 10 from a million records
我有一份报告显示 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)
}
如果我也可以使用其他数据结构,请告诉我。
谢谢
您可以使用优先级队列,因为它在 Java 中的作用类似于堆。参见 How does Java's PriorityQueue differ from a min-heap? If no difference, then why was it named PriorityQueue and not Heap?
热门算法使用最小堆(PriorityQueue
in Java),但您的算法中应该有一些大小检查。假设每个项目都有一个分数,你想收集分数最高的 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);
}
}
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();
}
}
excel 电子表格中有 40 亿条记录?不,你没有 https://superuser.com/questions/366468/what-is-the-maximum-allowed-rows-in-a-microsoft-excel-xls-or-xlsx
您应该在数据库上执行此操作,而不是依赖 java 实现。对于如此多的记录,它的效率必然低于优化的数据库查询。
我有一份报告显示 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)
}
如果我也可以使用其他数据结构,请告诉我。
谢谢
您可以使用优先级队列,因为它在 Java 中的作用类似于堆。参见 How does Java's PriorityQueue differ from a min-heap? If no difference, then why was it named PriorityQueue and not Heap?
热门算法使用最小堆(PriorityQueue
in Java),但您的算法中应该有一些大小检查。假设每个项目都有一个分数,你想收集分数最高的 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);
}
}
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();
}
}
excel 电子表格中有 40 亿条记录?不,你没有 https://superuser.com/questions/366468/what-is-the-maximum-allowed-rows-in-a-microsoft-excel-xls-or-xlsx
您应该在数据库上执行此操作,而不是依赖 java 实现。对于如此多的记录,它的效率必然低于优化的数据库查询。