问题描述:
给定一个 Element[] 类型的数组:
Element[] array = {new Element(1), new Element(2), new Element(3)};
如何将此数组转换为 ArrayList 类型的对象?
ArrayList arrayList = ???;
解决方案1:
huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感
new ArrayList<>(Arrays.asList(array));
是的。在(最常见的)您只需要一个列表的情况下,new ArrayList 调用也是不必要的。
@Luron - 只需使用 List list = Arrays.asList(array)
@Calum 和@Pool - 如下亚历克斯米勒的回答中所述,使用 Arrays.asList(array) 而不将其传递给新的 ArrayList 对象将修复列表的大小。使用 ArrayList 的更常见原因之一是能够动态更改其大小,而您的建议会阻止这种情况。
Arrays.asList() 是一个可怕的函数,你永远不应该直接使用它的返回值。它破坏了 List 模板,因此请始终以此处指示的形式使用它,即使它看起来确实是多余的。好答案。
@Adam 请研究 java.util.List 的 javadoc。 add 的合同允许他们抛出 UnsupportedOperationException。 docs.oracle.com/javase/7/docs/api/java/util/… 诚然,从面向对象的角度来看,很多时候您必须知道具体实现才能使用集合并不是很好 - 这是一种实用的设计选择,以保持框架简单。
解决方案2:
与HuntsBot一起,探索全球自由职业机会–huntsbot.com
鉴于:
Element[] array = new Element[] { new Element(1), new Element(2), new Element(3) };
最简单的答案是:
List list = Arrays.asList(array);
这将正常工作。但有一些注意事项:
从 asList 返回的列表具有固定大小。因此,如果您希望能够在代码的返回列表中添加或删除元素,您需要将其包装在一个新的 ArrayList 中。否则你会得到一个 UnsupportedOperationException。从 asList() 返回的列表由原始数组支持。如果修改原始数组,列表也会被修改。这可能令人惊讶。
Arrays.asList() 只是通过包装现有数组来创建一个 ArrayList,因此它是 O(1)。
包装在新的 ArrayList() 中将导致固定大小列表的所有元素被迭代并添加到新的 ArrayList 中,因此 O(n) 也是如此。
澄清一下,Arrays.asList() 创建了一个 java.util.Arrays.ArrayList(java.util.Arrays 中的静态嵌套类),而不是 java.util.ArrayList。
解决方案3:
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
(旧线程,但只有 2 美分,因为没有提到番石榴或其他库和其他一些细节)
如果可以,请使用番石榴
值得指出的是 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 factory methods 允许在大多数时间推断类型。然而,自从 Java 7 与新的菱形运算符一起出现以来,这个论点就不那么成立了。
但这不是唯一的原因(Java 7 还不是无处不在):速记语法也非常方便,并且方法初始化器(如上所示)允许编写更具表现力的代码。您可以在一个 Guava 调用中执行当前 Java 集合需要 2 的操作。
如果你不能…
对于不可变列表
使用 JDK 的 Arrays 类及其 asList() 工厂方法,用 Collections.unmodifiableList() 包装:
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.unmodifiableList() 包装。
如果您需要可变列表,请参阅下一步。
对于可变列表
与上面相同,但用实际的 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);
}
+1 但请注意,Arrays.asList 返回的 List 是可变的,因为您仍然可以 set 元素 - 它只是不可调整大小。对于没有 Guava 的不可变列表,您可能会提到 Collections.unmodifiableList。
解决方案4:
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。
由于这个问题已经很老了,令我惊讶的是,还没有人提出最简单的形式:
List arraylist = Arrays.asList(new Element(1), new Element(2), new Element(3));
从 Java 5 开始,Arrays.asList() 采用可变参数,您不必显式构造数组。
特别是,List a = Arrays.asList("first","second","third")
解决方案5:
huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感
new ArrayList(Arrays.asList(myArray));
确保 myArray 与 T 的类型相同。例如,如果您尝试从 int 数组创建 List,则会出现编译器错误。
解决方案6:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
另一种方式(虽然在性能方面基本上等同于 new ArrayList(Arrays.asList(array)) 解决方案:
Collections.addAll(arraylist, array);
解决方案7:
HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com
爪哇 9
在 Java 9 中,您可以使用 List.of 静态工厂方法来创建 List 文字。类似于以下内容:
List elements = List.of(new Element(1), new Element(2), new Element(3));
这将返回一个包含三个元素的 immutable 列表。如果您想要一个 mutable 列表,请将该列表传递给 ArrayList 构造函数:
new ArrayList<>(List.of(// elements vararg))
JEP 269:集合的便利工厂方法
JEP 269 为 Java Collections API 提供了一些便利的工厂方法。这些不可变的静态工厂方法内置于 Java 9 及更高版本的 List、Set 和 Map 接口中。
List.of() 不会按照原始问题中的要求返回 java.util.ArrayList 的实例。因此,只有第二个选项是有效的答案。
解决方案8:
HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com
您可能只需要一个列表,而不是一个 ArrayList。在这种情况下,您可以这样做:
List arraylist = Arrays.asList(array);
这将由原始输入数组支持,这就是您(可能)想要将其包装在新的 ArrayList 中的原因。
小心这个解决方案。如果你看,Arrays 不会返回一个真正的 java.util.ArrayList。它返回一个实现所需方法的内部类,但您不能更改列表中的成员。它只是一个数组的包装器。
您可以将 List 项目转换为 ArrayList
@Mikezx6r:小更正:这是一个固定大小的列表。您可以更改列表的元素(set 方法),但不能更改列表的大小(不是 add 或 remove 元素)!
是的,但需要注意的是,这取决于您要对列表执行的操作。值得注意的是,如果 OP 只是想遍历元素,则根本不需要转换数组。
解决方案9:
huntsbot.com – 高效赚钱,自由工作
另一个更新,即将于 2014 年结束,您也可以使用 Java 8:
ArrayList arrayList = Stream.of(myArray).collect(Collectors.toCollection(ArrayList::new));
如果这可能只是一个 List,则会保存一些字符
List list = Stream.of(myArray).collect(Collectors.toList());
最好不要依赖于实现,但 Collectors.toList() 实际上会返回一个 ArrayList。
错误使用 Stream.of(...);这将创建一个元素流。改用 Arrays.stream
我不这么认为,这两个选项是有效的,但 Arrays.stream 稍微“更好”,因为您可以使用带有“start”、“end”参数的重载方法以固定大小创建它。另请参阅:stackoverflow.com/a/27888447/2619091
解决方案10:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
如果您使用:
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
}
....
}
危险的一面是,如果你改变了初始数组,你就改变了 List !你确定你想要那个吗?可能是可能不是。
如果没有,最容易理解的方法是这样做:
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));
我喜欢使用 Collections、Arrays 或 Guava。但如果它不合适,或者你没有感觉,那就写另一条不雅的行来代替。
我看不出答案末尾的循环与您不鼓励使用的 new ArrayList(Arrays.asList(myArray)); 部分之间的根本区别。两者的作用完全相同,并且具有相同的复杂性。
Collections 在数组的开头创建一个指针。我的循环创建了许多指针:每个数组成员一个。因此,如果原始数组发生变化,我的指针仍然指向以前的值。
new ArrayList(Arrays.asList(myArray)); 做同样的事情,它将 asList 复制到 ArrayList...
解决方案11:
HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com
在 Java 9 中,您可以使用:
List list = List.of("Hello", "World", "from", "Java");
List list = List.of(1, 2, 3, 4, 5);
请注意,这不是一个 ArrayList,因为它被明确要求。
原文链接:https://www.huntsbot.com/qa/07dL/create-arraylist-from-array?lang=zh_CN
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会