内存和时间有效的方式来排序随机传入的数据

时间:2016-03-04 14:36:21

标签: java list sorting binary

我需要将来自不同随机值列表(值可以重复)的数据排序到内存中的唯一值列表和时间有效的方式(有数百个列表,每个列表最多可包含数千个记录) 。现在我有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倍(并且仍然使用相同的内存),两者都使用相同的比较器函数。

为什么这种性能差异?
有没有更有效的方法来做到这一点?

1 个答案:

答案 0 :(得分:1)

首先,很奇怪方法1比方法2慢20%,但我认为它是在非常小的集合上测试的。

导致方法2大幅放缓的原因有两个原因:

  1. 迭代时data没有排序,所以
  2. contains方法必须遍历整个列表才能找到元素 - O(n)。如果数据被排序,contains的O(n)复杂度没有米,因为它遍历整个集合。 因此,对于方法2,它是 O(n ^ 2)复杂性
  3. 对于方法1,您正在管理有序列表,并且您使用的是binarySearch O(ln(n))。 因此,方法1的复杂度为 O(n * ln(n))