我需要将来自不同随机值列表(值可以重复)的数据排序到内存中的唯一值列表和时间有效的方式(有数百个列表,每个列表最多可包含数千个记录) 。现在我有2个方法
方法1-按数据排序:
public List<ClassB> ListSorter1(List<ClassA> listA){
List<ClassB> data = new ArrayList<>();
for (ClassA a : listA) {
int idx = Collections.binarySearch(data, a.getValue());
if (idx < 0) {
int ip = -(idx + 1);
data.add(ip, a.getValue());
}
}
}
方法2 - 获取所有唯一数据,然后排序:
public List<ClassB> ListSorter2 (List<ClassA> listA){
List<ClassB> data = new ArrayList<>();
for (ClassA a : listA) {
if (!data.contains(a.getValue())) {
data.add(a.getValue());
}
}
Collections.sort(data);
}
我遇到的问题是,当<ClassB>
是简单数据(整数)时,方法2表现更好(比方法1大约快20%,内存使用大致相同),但是一旦我改为一个更复杂的类,排序列表所需的时间,比方法1多10倍(并且仍然使用相同的内存),两者都使用相同的比较器函数。
为什么这种性能差异?
有没有更有效的方法来做到这一点?
答案 0 :(得分:1)
首先,很奇怪方法1比方法2慢20%,但我认为它是在非常小的集合上测试的。
导致方法2大幅放缓的原因有两个原因:
data
没有排序,所以contains
方法必须遍历整个列表才能找到元素 - O(n)。如果数据被排序,contains
的O(n)复杂度没有米,因为它遍历整个集合。
因此,对于方法2,它是 O(n ^ 2)复杂性对于方法1,您正在管理有序列表,并且您使用的是binarySearch
O(ln(n))。
因此,方法1的复杂度为 O(n * ln(n))