2016-11-07 30 views
0

我有兩個ArrayLists AB。我需要結合這兩個ArrayLists。將來自ArrayList_ B的所有元素置於ArrayList_ A的特定位置。在ArrayList_ 最有效的方法(根據RAM/CPU消耗)將元素從一個ArrayList添加到另一個ArrayList到特定位置

元素組成的應該看起來像: a1b1a2b2a3b3 ....

但這樣做的最有效途徑,盡我所能。

規則:不要更改創建ArrayList_ B

正如你所看到的,在我的例子中最有效的方法是Method2。但對於巨大的ArrayList,它仍然非常慢。

請提出最有效的方法如何做到這一點。感謝您的關注:)。

公共類解決方案{

public static void main(String[] args) { 

    Method1(); 
    Method2(); 
    Method3(); 

} 

private static void Method3() { 
    ArrayList<Object> a = new ArrayList<>(); 
    ArrayList<Object> b = new ArrayList<>(); 

    for (int i = 0; i < Math.pow(2, 15); i++) { 
     a.add("a" + i); 
    } 
    for (int i = 0; i < Math.pow(2, 15); i++) { 
     b.add("b" + i); 
    } 

    ArrayList<Object> aa = new ArrayList<>(a); 
    a.ensureCapacity(2*aa.size()); 
    a.clear(); 

    long time1 = System.currentTimeMillis(); 


    for (int i = 0; i<b.size();i++) { 
     a.add(aa.get(i)); 
     a.add(b.get(i)); 
    } 
    long time2 = System.currentTimeMillis(); 

    System.out.println(time2 - time1); 
} 

private static void Method2() { 
    ArrayList<Object> a = new ArrayList<>(); 
    ArrayList<Object> b = new ArrayList<>(); 

    for (int i = 0; i < Math.pow(2, 15); i++) { 
     a.add("a" + i); 
    } 

    for (int i = 0; i < Math.pow(2, 15); i++) { 
     b.add("b" + i); 
    } 

    long time1 = System.currentTimeMillis(); 

    int size = a.size(); 
    a.add(b.get(0)); 
    for (int i = 1; i < size; i++) { 
     a.add(a.get(i)); 
     a.add(b.get(i)); 
    } 
    a.subList(1, size).clear(); 

    long time2 = System.currentTimeMillis(); 

    System.out.println(time2 - time1); 

} 

private static void Method1() { 
    ArrayList<Object> a = new ArrayList<>(); 
    ArrayList<Object> b = new ArrayList<>(); 

    for (int i = 0; i < Math.pow(2, 15); i++) { 
     a.add("a" + i); 
    } 

    for (int i = 0; i < Math.pow(2, 15); i++) { 
     b.add("b" + i); 
    } 

    long time1 = System.currentTimeMillis(); 

    a.add(1, b.get(0)); 
    for (int i = 1; i < b.size(); i++) { 
     a.add((2 * i + 1), b.get(i)); 
    } 

    long time2 = System.currentTimeMillis(); 

    System.out.println(time2 - time1); 
} 

}

+3

我會創建一個副本,清除它並再次構建。確保容量從一開始就是正確的,而不是增加容量。你可以使用'ensureCapacity(size * 2)'我也會確保代碼已經被加熱,反覆運行它,並忽略測試這段代碼的前2秒。 –

+2

我不知道會計算多少次'Math.pow(2,15)'。 – vitrums

+0

Peter Lawrey,謝謝你的建議,我會試試這封信。但是,例如,ArrayList *** A ***我有默認列表和ArrayList *** B ***作爲傳入參數。可能你有任何想法如何在不創建新列表的情況下提高效率? – 2kich

回答

0

彼得的回答可能是最好的。然而,如果你這麼做很多,也許定義你自己的班級。框架代碼,也許是馬車,假設你的兩個輸入數組a和b永遠不會改變,你永遠不希望創建等後更改組合列表...:

public class DualList<E> extends AbstractList<E> { 
    final List<E> a; 
    final List<E> b; 

    public DualList(List<E> a, List<E> b) { 
     this.a = a; this.b = b; 
    } 

    public E get(int idx) { 
     int half = idx >> 1; 
     if ((idx & 1) == 1) 
     return this.b.get(half); 
     else 
     return this.a.get(half); 
    } 

    // not sure what else you need or want to override... 
} 

這顯然是方式方法更快「創建」組合列表,因爲它幾乎不做任何事情,但是每次調用get()來檢索一個元素時,這會稍微慢一點。所以最後的決定取決於你打電話給多少次get()

+0

謝謝,這也有用,我會把它放在我的知識庫中! :) – 2kich

相關問題