从数组创建ArrayList

给定Element[]类型的数组:

Element[] array = {new Element(1), new Element(2), new Element(3)};
如何将此数组转换为ArrayList<Element>类型的对象?

ArrayList arrayList = ???;
new ArrayList<>(Arrays.asList(array));
2008-10-01 22:39:12
new ArrayList(Arrays.asList(myArray));
确保myArray的类型与T相同。例如,如果尝试从int数组创建List,则会出现编译器错误。

2008-10-01 22:40:46
您可能只需要一个List,而不是ArrayList。在这种情况下,您只需执行以下操作:

List arraylist = Arrays.asList(array);
2008-10-01 22:45:02
鉴于:

Element[] array = new Element[] { new Element(1), new Element(2), new Element(3) };
最简单的答案是:

List list = Arrays.asList(array);
这会很好的。但需要注意的是:

从asList返回的列表大小固定。因此,如果您希望能够在代码中添加或删除返回列表中的元素,则需要将其包装在新的ArrayList中。否则,您将获得UnsupportedOperationException。从asList()返回的列表由原始数组支持。如果修改原始数组,列表也将被修改。这可能令人惊讶。

2008-10-01 23:39:06
由于这个问题很古老,所以我很惊讶,还没有人提出最简单的形式:

List arraylist = Arrays.asList(new Element(1), new Element(2), new Element(3));
从Java5开始,Arrays.asList()采用varargs参数,不必显式构造数组。

2011-06-22 19:30:23
另一种方式(虽然本质上等同于新的ArrayList(array.asList(array))解决方案的性能:

Collections.addAll(arraylist, array);
2012-04-04 07:20:55
(旧线索,但只有2美分,因为没有提到番石榴或其他libs以及其他一些细节)

如果可以,请使用Guava

值得指出的是,Guava的方式大大简化了这些骗局:

用法

对于不可变列表

使用ImmutableList类及其of()和copyOf()工厂方法(元素不能为空):

List il = ImmutableList.of("string", "elements"); // from varargs
List il = ImmutableList.copyOf(aStringArray); // from array
对于可变列表

使用Lists类及其newArrayList()工厂方法:

List l1 = Lists.newArrayList(anotherListOrCollection); // from collection
List l2 = Lists.newArrayList(aStringArray); // from array
List l3 = Lists.newArrayList("or", "string", "elements"); // from varargs
还请注意其他类中其他数据结构的类似方法,例如Sets。

为什么选择Guava?

主要的吸引力可能是为了类型安全而减少泛型带来的混乱,因为使用Guava工厂方法可以在大多数时间推断类型。然而,自从Java7引入了新的diamond操作符以来,这一论点就不那么有效了。

但这并不是唯一的原因(Java7还没有普及):速记语法也非常方便,如上所述,方法初始化器允许编写更具表达力的代码。在当前的Java集合中,您只需一次Guava调用即可完成2。

如果你不能。。。

对于不可变列表

使用JDK的Arrays类及其asList()工厂方法,用Collections.unmodifiebleList()包装:

List l1 = Collections.unmodifiableList(Arrays.asList(anArrayOfElements));
List l2 = Collections.unmodifiableList(Arrays.asList("element1", "element2"));
请注意,asList()返回的类型是一个使用具体ArrayList实现的List,但它不是java.util.ArrayList。它是一个内部类型,它模拟ArrayList,但实际上直接引用传递的数组并使其“直写”(修改反映在数组中)。

它禁止通过简单扩展AbstractList(因此不支持添加或删除元素)的方式,通过某些List API的方法进行修改,但是它允许调用set()来覆盖元素。因此,这个列表不是真正不可变的,对asList()的调用应该用Collections.unmodifiebleList()包装。

如果需要可变列表,请参阅下一步。

对于可变列表

与上面相同,但用实际的java.util.ArrayList包装:

List l1 = new ArrayList(Arrays.asList(array)); // Java 1.5 to 1.6
List l1b = new ArrayList<>(Arrays.asList(array)); // Java 1.7+
List l2 = new ArrayList(Arrays.asList("a", "b")); // Java 1.5 to 1.6
List l2b = new ArrayList<>(Arrays.asList("a", "b")); // Java 1.7+
教育目的:良好的手工方式

// for Java 1.5+
static List arrayToList(final T[] array) {
final List l = new ArrayList(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);
}
2012-11-17 01:16:41
// Guava
import com.google.common.collect.ListsLists
...
List list = Lists.newArrayList(aStringArray);
2014-01-07 14:04:45
如果您使用:

new ArrayList(Arrays.asList(myArray));
您可以创建并填写两个列表!在一个大列表中填充两次正是您不想做的,因为每次需要扩展容量时,它都会创建另一个Object[]数组。

幸运的是,JDK实现速度很快,Arrays.asList(a[])做得很好。它创建一种名为Arrays.ArrayList的ArrayList,其中Object[]数据直接指向数组。

// in Arrays
@SafeVarargs
public static List asList(T... a) {
return new ArrayList<>(a);
}
//still in Arrays, creating a private unseen class
private static class ArrayList

private final E[] a;    
ArrayList(E[] array) {
    a = array; // you point to the previous array
}
....

}
危险的一面是,如果更改初始数组,则会更改列表!你确定你想要吗?也许是,也许不是。

如果不是,最容易理解的方法是这样做:

ArrayList list = new ArrayList(myArray.length); // you know the initial capacity
for (Element element : myArray) {
list.add(element);
}
或者如@glglgl所述,您可以创建另一个独立的ArrayList:

new ArrayList(Arrays.asList(myArray));
我喜欢使用集合、数组或番石榴。但如果它不合适,或者你感觉不到,就写另一行不雅的行。

文章出处 https://www.lum114.com/post/E3Agaqme5W

posted @ 2023-02-27 10:31  陈宏博  阅读(71)  评论(0编辑  收藏  举报