Java ArrayList 初始化等价于数组初始化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2760995/
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
ArrayList initialization equivalent to array initialization
提问by Jonathan
I am aware that you can initialize an array during instantiation as follows:
我知道你可以在实例化过程中初始化一个数组,如下所示:
String[] names = new String[] {"Ryan", "Julie", "Bob"};
Is there a way to do the same thing with an ArrayList? Or must I add the contents individually with array.add()
?
有没有办法用 ArrayList 做同样的事情?或者我必须单独添加内容array.add()
?
采纳答案by meriton
Arrays.asListcan help here:
Arrays.asList可以在这里提供帮助:
new ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21));
回答by jayshao
Well, in Java there's no literal syntax for lists, so you have to do .add().
好吧,在 Java 中,列表没有文字语法,因此您必须使用 .add()。
If you have a lot of elements, it's a bit verbose, but you could either:
如果你有很多元素,它有点冗长,但你可以:
- use Groovy or something like that
- use Arrays.asList(array)
- 使用 Groovy 或类似的东西
- 使用 Arrays.asList(array)
2 would look something like:
2 看起来像:
String[] elements = new String[] {"Ryan", "Julie", "Bob"};
List list = new ArrayList(Arrays.asList(elements));
This results in some unnecessary object creation though.
这会导致一些不必要的对象创建。
回答by Brian Agnew
Yes.
是的。
new ArrayList<String>(){{
add("A");
add("B");
}}
What this is actually doing is creating a class derived from ArrayList<String>
(the outer set of braces do this) and then declare a static initialiser (the inner set of braces). This is actually an innerclass of the containing class, and so it'll have an implicit this
pointer. Not a problem unless you want to serialise it, or you're expecting the outer class to be garbage collected.
这实际上是创建一个派生自的类ArrayList<String>
(外部大括号执行此操作),然后声明一个静态初始化程序(内部大括号组)。这实际上是包含类的内部类,因此它将有一个隐式this
指针。除非你想序列化它,或者你期望外部类被垃圾收集,否则这不是问题。
I understand that Java 7 will provide additional language constructsto do precisely what you want.
我知道 Java 7 将提供额外的语言结构来精确地做你想要的。
EDIT: recent Java versions provide more usable functions for creating such collections, and are worth investigating over the above (provided at a time prior to these versions)
编辑:最近的 Java 版本为创建此类集合提供了更多可用的功能,值得对上述内容进行研究(在这些版本之前的时间提供)
回答by Fred Haslam
Here is the closest you can get:
这是你能得到的最接近的:
ArrayList<String> list = new ArrayList(Arrays.asList("Ryan", "Julie", "Bob"));
You can go even simpler with:
您可以更简单地使用:
List<String> list = Arrays.asList("Ryan", "Julie", "Bob")
Looking at the source for Arrays.asList, it constructs an ArrayList, but by default is cast to List. So you could do this (but not reliably for new JDKs):
查看 Arrays.asList 的源代码,它构造了一个 ArrayList,但默认情况下会强制转换为 List。所以你可以这样做(但对于新的 JDK 不可靠):
ArrayList<String> list = (ArrayList<String>)Arrays.asList("Ryan", "Julie", "Bob")
回答by John D
Arrays.asList("Ryan", "Julie", "Bob");
回答by crsedgar
回答by Ken de Guzman
How about this one.
这个怎么样。
ArrayList<String> names = new ArrayList<String>();
Collections.addAll(names, "Ryan", "Julie", "Bob");
回答by NameSpace
The selected answer is: ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21));
选择的答案是: ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21));
However, its important to understand the selected answer internally copies the elements several times before creating the final array, and that there is a way to reduce some of that redundancy.
但是,在创建最终数组之前了解所选答案在内部多次复制元素很重要,并且有一种方法可以减少一些冗余。
Lets start by understanding what is going on:
让我们首先了解发生了什么:
First, the elements are copied into the
Arrays.ArrayList<T>
created by the static factoryArrays.asList(T...)
.This does not the produce the same class as
java.lang.ArrayList
despite having the same simple class name. It does not implement methods likeremove(int)
despite having a List interface. If you call those methods it will throw anUnspportedMethodException
. But if all you need is a fixed-sized list, you can stop here.Next the
Arrays.ArrayList<T>
constructed in #1 gets passed to the constructorArrayList<>(Collection<T>)
where thecollection.toArray()
method is called to clone it.public ArrayList(Collection<? extends E> collection) { ...... Object[] a = collection.toArray(); }
Next the constructor decides whether to adopt the cloned array, or copy it again to remove the subclass type. Since
Arrays.asList(T...)
internally uses an array of type T, the very same one we passed as the parameter, the constructor always rejects using the clone unless T is a pure Object. (E.g. String, Integer, etc all get copied again, because they extend Object).if (a.getClass() != Object[].class) { //Arrays.asList(T...) is always true here //when T subclasses object Object[] newArray = new Object[a.length]; System.arraycopy(a, 0, newArray, 0, a.length); a = newArray; } array = a; size = a.length;
首先,元素被复制到
Arrays.ArrayList<T>
由静态工厂创建的Arrays.asList(T...)
。java.lang.ArrayList
尽管具有相同的简单类名,但这不会产生相同的类。remove(int)
尽管有 List 接口,但它没有实现类似的方法。如果你调用这些方法,它会抛出一个UnspportedMethodException
. 但是,如果您只需要一个固定大小的列表,则可以到此为止。接下来
Arrays.ArrayList<T>
,#1 中构造的被传递给构造函数ArrayList<>(Collection<T>)
,在该构造函数中collection.toArray()
调用该方法来克隆它。public ArrayList(Collection<? extends E> collection) { ...... Object[] a = collection.toArray(); }
接下来构造函数决定是采用克隆的数组,还是再次复制它以删除子类类型。由于
Arrays.asList(T...)
内部使用 T 类型的数组,与我们作为参数传递的数组相同,构造函数总是拒绝使用克隆,除非 T 是纯对象。(例如,字符串、整数等都被再次复制,因为它们扩展了对象)。if (a.getClass() != Object[].class) { //Arrays.asList(T...) is always true here //when T subclasses object Object[] newArray = new Object[a.length]; System.arraycopy(a, 0, newArray, 0, a.length); a = newArray; } array = a; size = a.length;
Thus, our data was copied 3x just to explicitly initialize the ArrayList. We could get it down to 2x if we force Arrays.AsList(T...)
to construct an Object[] array, so that ArrayList can later adopt it, which can be done as follows:
因此,我们的数据被复制了 3 次,只是为了显式初始化 ArrayList。如果我们强制Arrays.AsList(T...)
构造一个 Object[] 数组,我们可以将其降低到 2 倍,以便 ArrayList 以后可以采用它,这可以按如下方式完成:
(List<Integer>)(List<?>) new ArrayList<>(Arrays.asList((Object) 1, 2 ,3, 4, 5));
Or maybe just adding the elements after creation might still be the most efficient.
或者在创建后添加元素可能仍然是最有效的。