给定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 = ???;
当前回答
(旧线索,但只有2美分,因为没有提到番石榴或其他libs以及其他一些细节)
如果可以,请使用Guava
值得指出的是,Guava的方式大大简化了这些骗局:
用法
对于不可变列表
使用ImmutableList类及其of()和copyOf()工厂方法(元素不能为空):
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?
主要的吸引力可能是为了类型安全而减少泛型带来的混乱,因为使用Guava工厂方法可以在大多数时间推断类型。然而,自从Java7引入了新的diamond操作符以来,这一论点就不那么有效了。
但这并不是唯一的原因(Java7还没有普及):速记语法也非常方便,如上所述,方法初始化器允许编写更具表达力的代码。在当前的Java集合中,您只需一次Guava调用即可完成2。
如果你不能。。。
对于不可变列表
使用JDK的Arrays类及其asList()工厂方法,用Collections.unmodifiebleList()包装:
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.unmodifiebleList()包装。
如果需要可变列表,请参阅下一步。
对于可变列表
与上面相同,但用实际的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);
}
其他回答
Java 9
在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:便利工厂收集方法
JEP269为Java集合API提供了一些方便的工厂方法。这些不可变的静态工厂方法内置在Java9和更高版本的List、Set和Map接口中。
另一种方式(虽然本质上等同于新的ArrayList(array.asList(array))解决方案的性能:
Collections.addAll(arraylist, array);
下面的代码似乎是很好的方法。
new ArrayList<T>(Arrays.asList(myArray));
在创建大量ArrayList并需要简洁语法时,我使用了以下helper方法:
import java.util.ArrayList;
import java.util.Arrays;
class Main {
@SafeVarargs
public static <T> ArrayList<T> AL(T ...a) {
return new ArrayList<T>(Arrays.asList(a));
}
public static void main(String[] args) {
var al = AL(AL(1, 2, 3, 4), AL(AL(5, 6, 7), AL(8, 9)));
System.out.println(al); // => [[1, 2, 3, 4], [[5, 6, 7], [8, 9]]]
}
}
Guava使用相同的方法,因此@SafeVarargs在这里看起来很安全。另请参阅Java SafeVarargs注释,是否存在标准或最佳实践?。
在调用Arrays接口时,还可以使用多态性声明ArrayList,如下所示:
List<Element>arraylist=newArrayList<Integer>(Arrays.asList(array));
例子:
Integer[] array = {1}; // autoboxing
List<Integer> arraylist = new ArrayList<Integer>(Arrays.asList(array));
这应该是一种魅力。