Java - 新的 ArrayList(List) 与空的 ArrayList() + add(element)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17041655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java - new ArrayList(List) vs empty ArrayList() + add(element)
提问by straville
I've learned today that you can create a new ArrayList object utilizing a static method like so:
我今天了解到您可以使用静态方法创建一个新的 ArrayList 对象,如下所示:
List<String> listDummy = Arrays.asList("Coding", "is", "fun");
ArrayList<String> stringList = new ArrayList<>(listDummy);
Or even more concisely:
或者更简洁:
ArrayList<String> stringList = new ArrayList<>(Arrays.asList("Coding", "is", "fun"));
My question is:How expensive is this performance-wise compared to the "traditional" way? (below)
我的问题是:与“传统”方式相比,这种性能方面的成本有多高?(以下)
ArrayList<String> stringList = new ArrayList<>();
stringList.add("Coding");
stringList.add("is");
stringList.add("fun");
I realize the upper way of creating an ArrayList includes an extra List object creation, however, I prefer the shorter and more compact syntax to an extent that I'm willing to sacrifice someperformance but gotta draw the line somewhere.
我意识到创建 ArrayList 的上层方法包括一个额外的 List 对象创建,但是,我更喜欢更短、更紧凑的语法,以至于我愿意牺牲一些性能但必须在某处划清界限。
PS. leaving the type information(<>) empty in "new ArrayList<>()" is a Java SE 7 feature, not an error.
附注。将“new ArrayList<>()”中的类型信息(<>) 留空是 Java SE 7 特性,而不是错误。
Thank you beforehand for any answers!
预先感谢您的任何答案!
采纳答案by Petr Jane?ek
The usual add()
way calls three methods.
通常的add()
方式调用三个方法。
The asList()
way makes an array, then does clone()
on it (which does a shallow copy), then does copy all the elements manually because of this bug. And afterwards, if you want to add another element to stringList
, the array will have to be made larger and elements re-copied, because the size was exact for the elements provided. (all this is implementation dependant and assumes Oracle JDK)
该asList()
方法创建一个数组,然后clone()
对其进行操作(进行浅复制),然后由于此错误而手动复制所有元素。之后,如果您想向 中添加另一个元素stringList
,则必须使数组变大并重新复制元素,因为所提供元素的大小是精确的。(所有这些都依赖于实现并假设 Oracle JDK)
For three elements, the latter will be slower, but for any practical use, it will be negligible. For many elements, the two approaches might get equal in performance and the former one mighteven get slower.
对于三个元素,后者会慢一些,但对于任何实际使用,都可以忽略不计。对于许多元素,这两种方法的性能可能相当,而前一种方法甚至可能会变慢。
Write what you think will read the best, the performance penalty is minimal and you should not care about it until it proves itself to be bottleneck.
写出你认为会读得最好的东西,性能损失很小,你不应该关心它,直到它证明自己是瓶颈。
All that said, if you're after consice syntax, you could like Google Guava's Lists
:
综上所述,如果您追求 consice 语法,您可能会喜欢 Google Guava 的Lists
:
List<String> stringList = Lists.newArrayList("Coding", "is", "fun");
I haven't used a classic ArrayList
constructor for quite a while now.
我已经有ArrayList
一段时间没有使用经典的构造函数了。
回答by Peter Lawrey
The performance difference is likely to be 30 - 300 ns depending on your system and how warmed up your code is. I suspect the performance difference is small.
性能差异可能为 30 - 300 ns,具体取决于您的系统和代码的预热程度。我怀疑性能差异很小。
I always say, if in doubt; write the code as simpler and clear as you can and it will often perform ok as well.
我总是说,如果有疑问;尽可能简单明了地编写代码,它通常也能正常运行。
回答by Bohemian
You can do it in one line without creating additional lists:
您可以在一行中完成,而无需创建其他列表:
ArrayList<String> stringList = new ArrayList<>(){{
add("Coding");
add("is");
add("fun");
}};
This is an anonymous class, which is a subclassof ArrayList, with an instance block.
这是一个匿名类,它是ArrayList的子类,带有一个实例块。
回答by Evgeniy Dorofeev
If you are not going to add /remove elements from the list after creation then the best way is not to create ArrayList at all, this will be really efficient
如果您不打算在创建后从列表中添加/删除元素,那么最好的方法就是根本不创建 ArrayList,这将非常有效
List<String> listDummy = Arrays.asList("Coding", "is", "fun");
otherwise new ArrayList<>(listDummy)
is more efficient than manual adding elements one by one, see ArrayList(Collection) src:
否则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);
}
it's optimized:
它的优化:
1) it creates the array of exact size
2) it uses native copying of elements
1) 它创建精确大小的数组
2) 它使用元素的本机复制
回答by Jan Thom?
The list you get from Arrays.asList is already an ArrayList, so it is not necessary to wrap it with an ArrayList again:
你从 Arrays.asList 得到的列表已经是一个 ArrayList,所以没有必要再用一个 ArrayList 包裹它:
public static <T> List<T> asList(T... a) {
return new ArrayList<T>(a);
}
Caveat: The list is read-only, so if you need to write it, you will need to wrap it indeed using new ArrayList(..).
警告:该列表是只读的,因此如果您需要编写它,则需要使用 new ArrayList(..) 将其包装起来。
Nevertheless, I think using Arrays.asList should be better than creating a list using repeated calls of "add", because the ArrayList's internal array is initialized with the correct size. So the best way would be
尽管如此,我认为使用 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"));
Also this is the most readable IMHO, and readability for me always wins over very small performance gains unless you really need that extra performance. If you really need to do performance tuning, use a profiler. The bottleneck is usually where you wouldn't expect it to be. A profiler can give you exact information about what parts of your program are slow and you can optimize them as needed.
这也是最易读的恕我直言,可读性对我来说总是胜过非常小的性能提升,除非你真的需要额外的性能。如果您确实需要进行性能调整,请使用分析器。瓶颈通常出现在您意想不到的地方。分析器可以为您提供有关程序哪些部分缓慢的准确信息,您可以根据需要对其进行优化。
回答by Grzegorz ?ur
The performance difference depends on size of the source array.
性能差异取决于源数组的大小。
If you are adding items one by one multiple reallocations inside destination array will happen.
如果您一一添加项目,则会在目标数组内进行多次重新分配。
If you are adding whole collection at once only one allocation should be done, because the size is known beforehand.
如果您一次添加整个集合,则只应进行一次分配,因为大小是事先知道的。
回答by maybeWeCouldStealAVan
I sometimes use a convenience function:
我有时会使用一个方便的功能:
public static <T> ArrayList<T> asArrayList(T... args) {
ArrayList<T> list = new ArrayList<T>(args.length);
Collections.addAll(list, args);
return list;
}
This is a bit quicker than the Arrays.asList
route. (Not that it would ever really matter for hard-coded lists.)
这比Arrays.asList
路线要快一些。(并不是说它对于硬编码列表真的很重要。)