3

假设我们尝试实现一个合并排序算法,给定一个数组数组来合并什么是更好的方法,这个:

public void merge(ArrayList<ArrayList<E>> a) {
    ArrayList<ArrayList<E>> tmp = new ArrayList<ArrayList<E>>() ;
    while (a.size()>1) {
        for (int i=1; i<a.size();i+=2) {
            tmp.add(merge(a.get(i-1),a.get(i)));
        }
        if (a.size()%2==1) tmp.add(a.get(a.size()-1));
        a = tmp;
        tmp = new ArrayList<ArrayList<E>>() ;
    }
}

或这个 :

public void merge(ArrayList<ArrayList<E>> a) {
    ArrayList<ArrayList<E>> tmp = new ArrayList<ArrayList<E>>(),tmp2  ;
    while (a.size()>1) {
        for (int i=1; i<a.size();i+=2) {
            tmp.add(merge(a.get(i-1),a.get(i)));
        }
        if (a.size()%2==1) tmp.add(a.get(a.size()-1));
        tmp2 = a;
        a = tmp;
        tmp = tmp2;
        tmp.clear();
    }
}

为了更清楚,我所做的是合并 a 中每一对邻居并将生成的合并数组放入外部数组数组tmp,合并所有对后,一种方法是清除a然后将tmp移动到a,然后将清除的 a移动到tmp。第二种方法是“抛出”旧的tmp并获得一个新的tmp ,而不是重用旧的 tmp。

4

2 回答 2

6

作为一般规则,不要花费精力尝试重用旧集合;它只会使您的代码更难阅读(并且通常不会给您带来任何实际好处)。仅当您的代码已经正常工作并且您有硬数字表明您的算法速度得到了提高时,才可以尝试这样的优化。

于 2012-04-17T19:45:28.640 回答
2
  1. 总是分配一个新的ArrayList并填充它,会导致更多的垃圾收集,这通常会减慢一切(次要 GC 很便宜但不是免费的)。

  2. 当需要调整内部数组的大小(调整大小很便宜但不是免费的)时,重用ArrayList将导致使用的更少。Arrays.copyOf()ArrayList

另一方面:clear()也会使数组内容无效,以允许 GC 收集未使用的对象,这当然也不是免费的。

不过,如果考虑执行速度,我会重用ArrayList.

于 2012-04-17T19:48:00.090 回答