给定一个类型为 Element[]
的数组:
Element[] array = {new Element(1), new Element(2), new Element(3)};
如何将这个数组转换为类型为ArrayList<Element>
的对象?
ArrayList<Element> arrayList = ???;
给定一个类型为 Element[]
的数组:
Element[] array = {new Element(1), new Element(2), new Element(3)};
如何将这个数组转换为类型为ArrayList<Element>
的对象?
ArrayList<Element> arrayList = ???;
new ArrayList<>(Arrays.asList(array));
给定:
Element[] array = new Element[] { new Element(1), new Element(2), new Element(3) };
最简单的答案是这样做:
List<Element> list = Arrays.asList(array);
这个方法将能够正常工作。但需要注意以下几点:
asList()
返回的列表大小是固定的。因此,如果您想在代码中添加或删除返回的列表元素,则需要将其包装在一个新的 ArrayList
中。否则会抛出一个 UnsupportedOperationException
异常。asList()
返回的列表由原始数组支持。如果修改原始数组,则列表也将被修改。这可能会令人惊讶。Arrays.asList()
创建的是 java.util.Arrays.ArrayList
(java.util.Arrays
中的静态嵌套类),而不是 java.util.ArrayList
。 - Christoffer Hammarström(虽然这是一篇旧帖子,但是没有提到Guava或其他库以及其他细节)
值得注意的是,Guava的方法大大简化了这些嬉皮士:
使用ImmutableList
类及其of()
和copyOf()
工厂方法 (元素不能为null):
List<String> il = ImmutableList.of("string", "elements"); // from varargs
List<String> il = ImmutableList.copyOf(aStringArray); // from array
使用Lists
类及其newArrayList()
工厂方法:
List<String> l1 = Lists.newArrayList(anotherListOrCollection); // from collection
List<String> l2 = Lists.newArrayList(aStringArray); // from array
List<String> l3 = Lists.newArrayList("or", "string", "elements"); // from varargs
Sets
中。
主要吸引力可能在于减少由于泛型而导致的混乱,因为Guava的工厂方法的使用大多数情况下允许推断类型。然而,自从Java 7推出了新的钻石操作符后,这个论点的说服力已经减弱了。
但这并不是唯一的原因(而且Java 7还没有到处都有):简写语法也非常方便,而且像上面所示的方法初始化器可以编写更具表现力的代码。您可以在一个Guava调用中完成当前Java集合需要2个调用的操作。
使用JDK的Arrays
类及其asList()
工厂方法,结合Collections.unmodifiableList()
进行包装:
List<String> l1 = Collections.unmodifiableList(Arrays.asList(anArrayOfElements));
List<String> l2 = Collections.unmodifiableList(Arrays.asList("element1", "element2"));
asList()
返回的类型是使用具体的ArrayList
实现的List
,但它不是java.util.ArrayList
。它是一个内部类型,模拟了一个ArrayList
,但实际上直接引用传递的数组并使其“写入”(修改反映在数组中)。AbstractList
,它禁止通过一些List
API方法进行修改(因此,添加或删除元素是不受支持的),但允许调用set()
来覆盖元素。因此,这个列表并不是真正的不可变的,对asList()
的调用应该用Collections.unmodifiableList()
包装起来。java.util.ArrayList
包装:List<String> l1 = new ArrayList<String>(Arrays.asList(array)); // Java 1.5 to 1.6
List<String> l1b = new ArrayList<>(Arrays.asList(array)); // Java 1.7+
List<String> l2 = new ArrayList<String>(Arrays.asList("a", "b")); // Java 1.5 to 1.6
List<String> l2b = new ArrayList<>(Arrays.asList("a", "b")); // Java 1.7+
// for Java 1.5+
static <T> List<T> arrayToList(final T[] array) {
final List<T> l = new ArrayList<T>(array.length);
for (final T s : array) {
l.add(s);
}
return (l);
}
// for Java < 1.5 (no generics, no compile-time type-safety, boo!)
static List arrayToList(final Object[] array) {
final List l = new ArrayList(array.length);
for (int i = 0; i < array.length; i++) {
l.add(array[i]);
}
return (l);
}
Arrays.asList
返回的 List
是可变的,因为您仍然可以使用 set
方法更改元素,它只是不可调整大小。如果要创建不可变列表并且没有 Guava 库,则可以考虑使用 Collections.unmodifiableList
。 - Paul Bellora由于这个问题相当老,让我感到惊讶的是还没有人提出最简单的形式:
List<Element> arraylist = Arrays.asList(new Element(1), new Element(2), new Element(3));
从Java 5开始,Arrays.asList()
方法接受可变参数(varargs),您无需显式构造数组。
List<String> a = Arrays.asList("first","second","third")
。 - 18446744073709551615new ArrayList<T>(Arrays.asList(myArray));
请确保myArray
与T
的类型相同。例如,如果您尝试从int
数组创建List<Integer>
,则会收到编译器错误。
在Java9中,你可以使用 List.of
静态工厂方法来创建一个List
字面值。类似于以下内容:
List<Element> elements = List.of(new Element(1), new Element(2), new Element(3));
ArrayList
构造函数:new ArrayList<>(List.of(// elements vararg))
JEP 269为Java Collections API提供了一些便利的工厂方法。这些不可变的静态工厂方法已经内置在Java 9及更高版本的List
、Set
和Map
接口中。
你可能只需要一个列表,而不是ArrayList。在这种情况下,您可以这样做:
List<Element> arraylist = Arrays.asList(array);
另一个更新,快要结束2014年了,你也可以使用Java 8来做到这一点:
ArrayList<Element> arrayList = Stream.of(myArray).collect(Collectors.toCollection(ArrayList::new));
如果只使用 List
,就可以节省一些字符。
List<Element> list = Stream.of(myArray).collect(Collectors.toList());
Collectors.toList()
方法实际上返回的是一个ArrayList
。 - bcsb1001如果您使用:
new ArrayList<T>(Arrays.asList(myArray));
您可以创建并填充两个列表!重复填充一个大列表正是您不想做的,因为每次需要扩展容量时都会创建另一个Object[]
数组。
幸运的是,JDK实现很快,Arrays.asList(a[])
非常出色。它创建了一种名为 Arrays.ArrayList 的 ArrayList,其中 Object[] 数据直接指向数组。
// in Arrays
@SafeVarargs
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
//still in Arrays, creating a private unseen class
private static class ArrayList<E>
private final E[] a;
ArrayList(E[] array) {
a = array; // you point to the previous array
}
....
}
ArrayList<Element> list = new ArrayList<Element>(myArray.length); // you know the initial capacity
for (Element element : myArray) {
list.add(element);
}
或者像@ glglgl所说的那样,您可以创建另一个独立的ArrayList:
new ArrayList<T>(Arrays.asList(myArray));
我喜欢使用Collections
,Arrays
或Guava。但如果不适合或者你感觉不舒服,就写另一行不太优美的代码。
new ArrayList<T>(Arrays.asList(myArray));
部分之间的根本区别。两者都做了相同的事情,并具有相同的复杂度。 - glglglnew ArrayList<T>(Arrays.asList(myArray));
的作用是将 asList
复制到一个 ArrayList
中... - glglgl
new ArrayList
调用也是不必要的。 - CalumList<ClassName> list = Arrays.asList(array)
即可,此代码可以将数组转换为列表。 - Pool