[英]Java - new ArrayList(List) vs empty ArrayList() + add(element)
我今天已經了解到你可以使用靜態方法創建一個新的ArrayList對象,如下所示:
List<String> listDummy = Arrays.asList("Coding", "is", "fun");
ArrayList<String> stringList = new ArrayList<>(listDummy);
或者更簡潔:
ArrayList<String> stringList = new ArrayList<>(Arrays.asList("Coding", "is", "fun"));
我的問題是:與“傳統”方式相比,這種表現有多貴? (下面)
ArrayList<String> stringList = new ArrayList<>();
stringList.add("Coding");
stringList.add("is");
stringList.add("fun");
我意識到創建一個ArrayList的上層方法包括一個額外的List對象創建,但是,我更喜歡更短更緊湊的語法,以至於我願意犧牲一些性能,但必須在某處畫線。
PS。 在“new ArrayList <>()”中保留類型信息(<>)為空是Java SE 7的功能,而不是錯誤。
先謝謝你的回答!
性能差異可能為30 - 300 ns,具體取決於您的系統以及代碼的預熱程度。 我懷疑性能差異很小。
我總是說,如果有疑問; 盡可能簡單明了地編寫代碼,並且它通常也會運行正常。
通常的add()
方式調用三個方法。
asList()
方式創建一個數組,然后對其執行clone()
(執行淺拷貝),然后由於此錯誤而手動復制所有元素。 然后,如果要向stringList
添加另一個元素,則必須使該數組更大並重新復制元素,因為所提供的元素的大小是精確的。 (所有這些都取決於實現並假設Oracle JDK)
對於三個元素,后者將更慢,但對於任何實際使用,它將是可以忽略不計的。 對於許多元素,這兩種方法在性能上可能相同,前者可能會變得更慢。
寫下您認為最好的內容,性能損失最小,在您證明自己是瓶頸之前,您不應該關心它。
所有這一切,如果您使用consice語法,您可能會喜歡Google Guava的Lists
:
List<String> stringList = Lists.newArrayList("Coding", "is", "fun");
我現在已經有一段時間沒有使用經典的ArrayList
構造函數了。
您可以在一行中執行此操作而無需創建其他列表:
ArrayList<String> stringList = new ArrayList<>(){{
add("Coding");
add("is");
add("fun");
}};
這是一個匿名類,它是ArrayList的子類 ,帶有一個實例塊。
如果您不打算在創建后添加/刪除列表中的元素,那么最好的方法是不創建ArrayList,這將非常有效
List<String> listDummy = Arrays.asList("Coding", "is", "fun");
否則new ArrayList<>(listDummy)
比手動逐個添加元素更有效,請參閱ArrayList(Collection)src:
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
它被優化:
1)它創建精確大小的數組
2)它使用元素的原生復制
從Arrays.asList獲得的列表已經是一個ArrayList,因此沒有必要再次使用ArrayList包裝它:
public static <T> List<T> asList(T... a) {
return new ArrayList<T>(a);
}
警告:列表是只讀的,所以如果你需要編寫它,你需要使用新的ArrayList(..)來包裝它。
不過,我認為使用Arrays.asList應該比使用“add”的重復調用創建列表更好,因為ArrayList的內部數組是用正確的大小初始化的。 所以最好的方法是
List<String> myList= Arrays.asList("Coding", "is", "fun");
// or if you need to write the list
List<String> myList = new ArrayList(Arrays.asList("Coding", "is", "fun"));
這也是最易讀的恕我直言,除非你真的需要額外的性能,否則我的可讀性總是會贏得非常小的性能提升。 如果您確實需要進行性能調整,請使用分析器。 瓶頸通常是你不希望的。 探查器可以為您提供有關程序哪些部分較慢的確切信息,您可以根據需要對其進行優化。
性能差異取決於源陣列的大小。
如果要逐個添加項目,則會在目標陣列中進行多次重新分配。
如果要立即添加整個集合,則只應進行一次分配,因為事先已知大小。
我有時使用便利功能:
public static <T> ArrayList<T> asArrayList(T... args) {
ArrayList<T> list = new ArrayList<T>(args.length);
Collections.addAll(list, args);
return list;
}
這比Arrays.asList
路由快一點。 (並不是說硬編碼列表真的很重要。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.