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

时间:2013-06-11 10:12:55

标签: java arraylist

我今天已经了解到你可以使用静态方法创建一个新的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"));

我的问题是:与传统的&#34;相比,这种表现有多贵?办法? (下)

ArrayList<String> stringList = new ArrayList<>();
stringList.add("Coding");
stringList.add("is");
stringList.add("fun");

我意识到创建一个ArrayList的上层方法包括一个额外的List对象创建,但是,我更喜欢更短更紧凑的语法,以至于我愿意牺牲某些性能但必须在某处画线。

PS。将类型信息(&lt;&gt;)留空&#34; new ArrayList&lt;&gt;()&#34;是Java SE 7的功能,而不是错误。

预先感谢您的任何答案!

7 个答案:

答案 0 :(得分:5)

性能差异可能为30 - 300 ns,具体取决于您的系统以及代码的预热程度。我怀疑性能差异很小。

我总是说,如果有疑问;尽可能简单明了地编写代码,并且通常也可以正常运行。

答案 1 :(得分:2)

通常add()方式调用三种方法。

asList()方式生成一个数组,然后对其执行clone()(执行浅副本),然后由于this bug手动复制所有元素。然后,如果要向stringList添加另一个元素,则必须使该数组更大并重新复制元素,因为所提供的元素的大小是精确的。 (所有这些都取决于实现,并假设是Oracle JDK)

对于三个元素,后者会较慢,但对于任何实际应用,它都可以忽略不计。对于许多元素,这两种方法的性能可能相同,而前者可能甚至会变慢。

写下你认为最好读的内容,性能损失很小,在你证明自己是瓶颈之前你不应该关心它。


所有这一切,如果您使用consice语法,您可能会喜欢Google Guava的Lists

List<String> stringList = Lists.newArrayList("Coding", "is", "fun");

我现在已经有一段时间没用经典的ArrayList构造函数了。

答案 2 :(得分:1)

您可以在一行中执行此操作,而无需创建其他列表:

ArrayList<String> stringList = new ArrayList<>(){{
    add("Coding");
    add("is");
    add("fun");
}};

这是一个匿名类,它是ArrayList的子类,带有一个实例块。

答案 3 :(得分:1)

如果您不打算在创建后添加/删除列表中的元素,那么最好的方法是根本不创建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)它使用元素的原生复制

答案 4 :(得分:1)

从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"));

这也是最易读的恕我直言,除非你真的需要额外的性能,否则我的可读性总是会赢得非常小的性能提升。如果您确实需要进行性能调整,请使用分析器。瓶颈通常是你不希望的。探查器可以为您提供有关程序哪些部分较慢的确切信息,您可以根据需要对其进行优化。

答案 5 :(得分:0)

性能差异取决于源数组的大小。

如果要逐个添加项目,则会在目标数组中进行多次重新分配。

如果要立即添加整个集合,则只应进行一次分配,因为事先已知大小。

答案 6 :(得分:0)

我有时使用便利功能:

public static <T> ArrayList<T> asArrayList(T... args) {
    ArrayList<T> list = new ArrayList<T>(args.length);
    Collections.addAll(list, args);
    return list;
}

这比Arrays.asList路线快一点。 (并不是说硬编码列表真的很重要。)