2012-06-01 96 views
3

This API call返回一個潛在的大名單<字符串>,這是沒有排序。我需要對它進行排序,搜索並訪問隨機元素。目前,列表是通過一個ArrayList實現的(我檢查了源代碼),但在未來的某個未知點,API開發人員可能會選擇切換到LinkedList實現(不更改接口)。如何列出<String>轉換到一個ArrayList <String>

對我的程序進行排序,搜索,訪問潛在的大LinkedList會非常緩慢和不可接受。因此我需要將List轉換爲ArrayList以確保我的程序的實際效率。但是,由於列表最有可能是一個ArrayList,因此不必要地創建列表的新ArrayList副本將是低效的。

由於這些限制,我想出了下面的方法列表轉換成一個ArrayList:

private static <T> ArrayList<T> asArrayList(List<T> list) { 
    if (list instanceof ArrayList) { 
    return (ArrayList<T>) (list); 
    } else { 
    return new ArrayList<T>(list); 
    } 
} 

我的問題是:這是最有效的方式用List工作與未知實施?有沒有更好的方法將List轉換爲ArrayList?有沒有比List轉換爲ArrayList更好的選擇?

+0

你知道它有多大(尺寸)嗎?除非它真的很大並導致性能問題,否則我只會使用複製構造函數。 – assylias

+0

大概在5,000到50,000之間,該方法將被稱爲數萬次。 – dln385

+0

在包含100,000個項目的列表中使用複製構造函數在我的臺式電腦上使用少於0.5ms(在JIT進入之後)。現在演員陣容快了大約1000倍;-) – assylias

回答

4

你不可能真的比你得到的更簡單 - 看起來效率可能高於我。這就是說,這聽起來很像過早的優化 - 只有當您使用的API的作者更改爲LinkedList時,您才應該真的需要擔心這一點。如果您現在擔心,您可能會花費大量的時間和精力爲將來的情況進行規劃,這可能甚至不會發生 - 這個時間可能更適合尋找其他問題進行修復。大概你唯一需要改變的API版本是在你自己的應用程序版本之間 - 在那個時候處理這​​個問題,如果有的話。

2

正如您所看到的那樣,代碼很簡單,而且效率很高,因爲它只在必要時創建副本。

所以答案是沒有明顯更好的選擇,除了完全不同類型的解決方案,例如也可以對列表進行排序。

(記住,優化這個級別很少需要,所以它不是一個很常見的問題)

更新:只是一個afterthoughtL作爲一般規則,精心編寫的API不返回數據類型這對於它們可能包含的數據量是不合適的。這並不是說你應該盲目信任他們,但這不是一個完全不合理的假設。

0

支持高效隨機訪問的Java集合實現了RandomAccess標記接口。對於這樣的列表,您可以直接在列表上運行Collections.sort。對於沒有隨機訪問的列表,您應該使用其中一個toArray方法將列表轉儲到數組,然後對該數組進行排序,然後將其包裝到隨機訪問List中。

T[] array = (T[])list.toArray(); // just suppress the warning if the compiler worries about unsafe cast 
Arrays.sort(array); 
List<T> sortedList = Arrays.asList(array); 

我覺得其實Arrays.asList創建ArrayList,所以你可以嘗試鑄造它的結果,如果你喜歡。

Collections.sort對所有List的實現都是有效的,只要它們提供有效的ListIterator即可。該方法將列表轉儲到數組中,對其進行排序,然後使用ListIterator將值複製回O(n)中的列表中。

+0

'Arrays.asList()'不會創建一個數組列表(當然,它會返回一個'Arrays.ArrayList'內部類類型:))但是一個由實際數組支持的列表。 – biziclop

+0

好的。這就是爲什麼命名你的課程很重要。在同一個包中有兩個同名的類,一個是公共頂級類,另一個是內部類,只是混淆了。 :) – Wormbo

+0

問我怎麼找到了這:) – biziclop

1

對我的程序進行排序,搜索,訪問潛在的大LinkedList會非常緩慢和不可接受。

實際上,它並沒有那麼糟糕。 IIRC中,Collections.sort方法將列表複製到一個臨時數組中,對數組進行排序,然後將數組複製回原始列表。對於足夠大的列表,O(NlogN)排序階段將主宰O(N)複製階段。

相關問題