簡體   English   中英

Java - 新的ArrayList(List)vs empty ArrayList()+ add(element)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM