Java 如何有效地对一百万个元素进行排序?
我需要将大约60.000个元素与935.000个元素的列表进行比较,如果它们匹配,我需要进行计算 我已经实现了所需的一切,但这个过程大约需要40分钟。我在两个列表中都有一个唯一的7位数字。935.000和60.000文件未排序。在我尝试查找元素之前对大列表进行排序(哪种排序?)是否更有效?请记住,我每月只需要做一次计算,所以我不需要每天重复这个过程 基本上哪个更快:Java 如何有效地对一百万个元素进行排序?,java,performance,sorting,arraylist,Java,Performance,Sorting,Arraylist,我需要将大约60.000个元素与935.000个元素的列表进行比较,如果它们匹配,我需要进行计算 我已经实现了所需的一切,但这个过程大约需要40分钟。我在两个列表中都有一个唯一的7位数字。935.000和60.000文件未排序。在我尝试查找元素之前对大列表进行排序(哪种排序?)是否更有效?请记住,我每月只需要做一次计算,所以我不需要每天重复这个过程 基本上哪个更快: 非排序线性搜索 首先对列表进行排序,然后使用其他算法进行搜索 对两个列表进行排序,然后同时对这两个列表进行迭代,效果会非常好 使
- 非排序线性搜索
- 首先对列表进行排序,然后使用其他算法进行搜索
但实际上,由于您希望找到两个列表的交集,因此最好只使用
longList.retainAll(shortList)
来获得两个列表的交集。然后,您可以在大约O(1)的时间内对这两个列表执行您想要的任何操作,因为不需要实际查找任何内容。对这两个列表进行排序,然后同时迭代这两个列表
使用collections.sort()对列表进行排序
您可以从每个排序列表的索引开始,基本上直接遍历它。从短列表中的第一个元素开始,将其与长列表中的第一个元素进行比较。如果长列表中的某个元素的7位数字高于短列表中的当前数字,请增加短列表的索引。这样就不需要检查元素两次
但实际上,由于您希望找到两个列表的交集,因此最好只使用longList.retainAll(shortList)
来获得两个列表的交集。然后,您可以在大约O(1)的时间内对这两个列表执行您想要的任何操作,因为不需要实际查找任何内容。尝试一下
您有Collections.sort()
,它将为您完成繁重的工作,还有Collections.binarySearch()
,它将允许您在排序列表中查找元素。尝试一下
您有
Collections.sort()
,这将为您带来繁重的负担,还有Collections.binarySearch()
,它将允许您在已排序的列表中查找元素。当您搜索未排序的列表时,您必须平均查找一半的元素,然后才能找到您要查找的元素。如果在935000个元素的列表中执行60000次,那么结果大约是
935000*1/2*60000=28050000000次操作
如果首先对列表进行排序(使用mergesort),将需要大约n*log(n)个操作。然后,您可以使用二进制搜索在日志(n)查找中查找短列表中60000个元素中的每个元素。差不多
935000*日志(935000)+日志(935000)*60000=19735434次操作
如果先对列表进行排序,然后使用利用排序后的列表的搜索算法,速度应该会快得多。搜索未排序的列表时,在找到要查找的元素之前,您必须平均查看一半的元素。如果在935000个元素的列表中执行60000次,那么结果大约是 935000*1/2*60000=28050000000次操作 如果首先对列表进行排序(使用mergesort),将需要大约n*log(n)个操作。然后,您可以使用二进制搜索在日志(n)查找中查找短列表中60000个元素中的每个元素。差不多 935000*日志(935000)+日志(935000)*60000=19735434次操作
如果您先对列表进行排序,然后使用利用排序后的列表的搜索算法,则速度应该会快得多。您可以根据需要对两个列表进行排序,并按第一个或第二个索引(
i
和j
在下面的示例中)逐元素递增进行比较:
List<Comparable> first = ....
List<Comparable> second = ...
Collections.sort(first);
Collections.sort(second);
int i = 0;
int j = 0;
while (i < first.size() && j < second.size()) {
if (first.get(i).compareTo(second.get(j)) == 0) {
// Action for equals
}
if (first.get(i).compareTo(second.get(j)) > 0) {
j++;
} else {
i++;
}
}
List first=。。。。
第二个列表=。。。
集合。排序(第一);
集合。排序(第二);
int i=0;
int j=0;
而(i0){
j++;
}否则{
i++;
}
}
此代码的复杂度为O(n log(n)),其中n是最大的列表大小。您可以根据需要对两个列表进行排序,并按第一个或第二个索引(
i
和j
中的第一个或第二个索引)逐元素进行比较:
List<Comparable> first = ....
List<Comparable> second = ...
Collections.sort(first);
Collections.sort(second);
int i = 0;
int j = 0;
while (i < first.size() && j < second.size()) {
if (first.get(i).compareTo(second.get(j)) == 0) {
// Action for equals
}
if (first.get(i).compareTo(second.get(j)) > 0) {
j++;
} else {
i++;
}
}
List first=。。。。
第二个列表=。。。
集合。排序(第一);
集合。排序(第二);
int i=0;
int j=0;
而(i0){
j++;
}否则{
i++;
}
}
这段代码的复杂度是O(n log(n)),其中n是最大的列表大小。迭代已排序的集合以查找元素是无效的。二进制搜索是一种方法,不一定。在这种情况下(在一个长列表中搜索成吨的元素),它实际上可能相当快,因为它不需要搜索整个列表。通过保持索引,您将大大减少负载。好的,我知道您在那里做了什么。首先,我以为你的意思是带“静态”边界的(;;){(;){…}