从数组创建ArrayList

我有一个初始化的数组,如:

Element[] array = {new Element(1), new Element(2), new Element(3)};

我想将此数组转换为ArrayList类的对象.

ArrayList<Element> arraylist = ???;

回答

new ArrayList<>(Arrays.asList(array))
  • 是的.在(最常见的)你只想要一个列表的情况下,`new ArrayList`调用也是不必要的.
  • @Calum和@Pool - 如下所述,在Alex Miller的回答中,使用`Arrays.asList(array)`而不将其传递给新的`ArrayList`对象将修复列表的大小.使用`ArrayList`的一个常见原因是能够动态地改变它的大小,你的建议会阻止这种情况.
  • @Luron - 只需使用`List <ClassName> list = Arrays.asList(array)`
  • Arrays.asList()是一个可怕的函数,你永远不应该只使用它的返回值.它打破了List模板,所以总是以这里指出的形式使用它,即使它看起来多余.好答案.
  • @Adam请研究java.util.List的javadoc.add的合约允许它们抛出UnsupportedOperationException.http://docs.oracle.com/javase/7/docs/api/java/util/List.html#add%28E%29不可否认,从面向对象的角度来看,很多时候你不得不这么做了解具体实现以便使用集合 - 这是一个实用的设计选择,以保持框架简单.
  • @Adam`Arrays.asList()`是一个非常有用的方法,当你想要一个特定数组支持的列表时.例如`Collections.shuffle(Arrays.asList(myarray))`shuffle*original*array.
  • 我想指出,如果要使用迭代器执行mutative(如remove)操作,则需要新的ArrayList <Element>(...)部分.
  • 需要注意的是:我只是遇到了Java 6的不当行为:当Element是一个原语(例如数组是int [])时,asList创建了List <int []>.
  • @Arkadiy当`a`是`int []`时,`Arrays.asList(a).get(0)== a`并不是一个错误.这是因为`asList(Object ...)`varargs如何解析.一个类型为`int []`的对象是一个`Object`,而不是一个`Object []`,所以`Arrays.asList`正在传递一个带有一个元素的`Object`数组:一个`int`数组.
  • 当数组的类型为`int []`并且等效的用例如下时,这不会编译:`List <Integer> intList = new ArrayList <Integer>(Arrays.asList(intArray));`
  • @lbalazscs是真的,但我会说这非常接近黑客(即使shuffle方法是打算以这种方式使用),因为你基本上是在欺骗它,因为它认为它处理的是List而不是.很方便,但我仍然说这是一个可怕的功能.我的论点基本上是asList()方法具有误导性,因为它看起来像返回给定数组的List表示,而实际上它返回一个仅部分实现的List表示.
  • @AndrewF我明白为什么会这样.这只是为我打破DWIM,就是这样.
  • Arrays.asList(array).remove(key)将抛出:`java.util.AbstractList.remove(AbstractList.java:161)中的线程"main"java.lang.UnsupportedOperationException中的异常...` - dunno how [ `AbstractList`](http://docs.oracle.com/javase/7/docs/api/java/util/AbstractList.html)进入那里,但是在调用remove时你不想要它
  • 对于数组为基本类型(例如int [])的情况,请参见以下问题:http://stackoverflow.com/questions/1073919/how-to-convert-int-into-listinteger-in-java
  • 另外,`List <Element> list = new ArrayList <>(Arrays.asList(array));`就足够了.[diamond](http://stackoverflow.com/questions/4166966/what-is-the-point-of-the-diamond-operator-in-java-7)运算符将为您执行类型推断.
  • 这对Java 1.8不起作用.在Java 1.8中,`Arrays.asList(array)`将创建一个列表,其唯一的元素是`array`.结果列表不包含`array`的元素.

鉴于:

Element[] array = new Element[] { new Element(1), new Element(2), new Element(3) };

最简单的答案是:

List<Element> list = Arrays.asList(array);

这样可以正常工作.但有些警告:

  1. 从asList返回的列表具有固定大小.因此,如果您希望能够在代码中添加或删除返回列表中的元素,则需要将其包装在新代码中ArrayList.否则你会得到一个UnsupportedOperationException.
  2. 返回的列表asList()由原始数组支持.如果修改原始数组,则也会修改列表.这可能会令人惊讶.
  • Arrays.asList()只是通过包装现有数组来创建一个ArrayList,因此它是O(1).
  • 包装新的ArrayList()将导致固定大小列表的所有元素被迭代并添加到新的ArrayList,因此是O(n).
  • asList()返回的List的实现没有实现List的几个方法(如add(),remove(),clear()等等),这解释了UnsupportedOperationException.绝对是一个警告......
  • 当问题要求"ArrayList类的一个对象"时,我认为假设它引用的类是`java.util.ArrayList`是合理的.Arrays.asList实际上返回一个`java.util.Arrays.ArrayList`,它不是另一个类的`instanceof`.所以第三个警告是,如果你试图在需要上述内容的环境中使用它,它将无法工作.
  • 两种操作的时间复杂度是多少?我的意思是使用和不使用明确的arraylist结构.

(老线程,但只有2美分,因为没有提到番石榴或其他图书馆和其他一些细节)

如果可以,请使用番石榴

值得指出的是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.

为何选择番石榴?

主要的吸引力可能是减少因类型安全的仿制药造成的混乱,因为使用番石榴工厂方法可以在大多数时间推断出类型.然而,自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()List使用具体ArrayList实现,但它不是 java.util.ArrayList.它是一个内部类型,它模拟ArrayList但实际上直接引用传递的数组并使其"直写"(修改反映在数组中).

它禁止通过List简单扩展一些API的方法进行修改AbstractList(因此,不支持添加或删除元素),但它允许调用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);
}
  • +1但请注意,`Arrays.asList`返回的`List`是可变的,因为你仍然可以`set`元素 - 它只是不可调整大小.对于没有Guava的不可变列表,你可能会提到[`Collections.unmodifiableList`](http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#unmodifiableList (java.util.List) )).

由于这个问题已经很久了,所以没有人提出最简单的表格让我感到惊讶:

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")`

new ArrayList<T>(Arrays.asList(myArray));
new ArrayList<T>(Arrays.asList(myArray));
new ArrayList<T>(Arrays.asList(myArray));
new ArrayList<T>(Arrays.asList(myArray));

确保它myArray的类型相同T.例如,如果您尝试List<Integer>从数组中创建一个数组,则会出现编译器错误int.


Collections.addAll(arraylist, array);

>

另一种方式(尽管基本上等同于new ArrayList(Arrays.asList(array))解决方案性能方面:

Collections.addAll(arraylist, array);

Java 9

在Java 9中,您可以使用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:收集的便利工厂方法

JEP 269为Java Collections API 提供了一些便利工厂方法.这些一成不变的静态工厂方法被内置到List,SetMapJava中9以及更高的接口.


您可能只需要一个List,而不是ArrayList.在这种情况下,您可以这样做:

List<Element> arraylist = Arrays.asList(array);
  • 小心这个解决方案.如果你看,Arrays不会返回一个真正的java.util.ArrayList.它返回一个实现所需方法的内部类,但您无法更改列表中的成员.它只是一个数组的包装器.
  • @ Mikezx6r:小**校正**:这是一个固定大小的列表.你可以改变列表的元素(`set`方法),你不能改变列表的大小(不是'add`或`remove`元素)!
  • 这将由原始输入数组支持,这就是您(可能)想要将其包装在新的ArrayList中的原因.

另一个更新,即将结束的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`.

如果您使用:

可以创建并填写两个列表!填充两次大清单正是您不想做的事情,因为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:

我爱用Collections,Arrays或番石榴.但如果它不适合,或者你感觉不适合,那就改写另一条不优雅的线.


Java 9你可以使用:

List<String> list = List.of("Hello", "World", "from", "Java");
List<Integer> list = List.of(1, 2, 3, 4, 5);

根据问题,使用java 1.7的答案是:

ArrayList<Element> arraylist = new ArrayList<Element>(Arrays.<Element>asList(array));

但是最好总是使用界面:

List<Element> arraylist = Arrays.<Element>asList(array);

// Guava
import com.google.common.collect.ListsLists
...
List<String> list = Lists.newArrayList(aStringArray);

您可以使用不同的方法转换

有关更多详细信息,请参阅http://javarevisited.blogspot.in/2011/06/converting-array-to-arraylist-in-java.html


正如所有人所说,这样做会

 new ArrayList<>(Arrays.asList("1","2","3","4"));

创建数组的常见最新方法是observableArrays

ObservableList:允许侦听器在发生更改时跟踪的列表.

对于Java SE,您可以尝试

FXCollections.observableArrayList(new Element(1), new Element(2), new Element(3));

这是根据Oracle Docs

更新Java 9

在Java 9中它也有点简单:

List<String> list = List.of("element 1", "element 2", "element 3");

从Java 8开始,有一种更简单的转换方法:

public static <T> List<T> fromArray(T[] array) {
return Arrays.stream(array).collect(toList());
}

您也可以使用Java 8中的流来完成.

 List<Element> elements = Arrays.stream(array).collect(Collectors.toList());
  • 从** java 8 **开始,`Collectors.toList()`将返回`ArrayList`。但是这在Java的未来版本中可能会有所不同。如果您想要特定类型的集合,请使用Collectors.toCollection()代替,在那里您可以指定要创建的确切集合类型。

  1.  public static <T> List<T> asList(T... a) //varargs are of T type.
    

    所以,你可能会这样初始化arraylist:

     List<Element> arraylist = Arrays.asList(new Element(1),new Element(2),new Element(3));
    
  2. public static <T> boolean addAll(Collection<? super T> c, T... a);
    

    所以,这段代码也很有用


另一种简单的方法是使用for-each循环将数组中的所有元素添加到新的ArrayList中.

ArrayList<Element> list = new ArrayList<>();
for(Element e : array)
list.add(e);

如果数组是原始类型,则给定的答案将不起作用.但是从Java 8开始,您可以使用:

int[] array = new int[5];
Arrays.stream(array).boxed().collect(Collectors.toList());

使用以下代码将元素数组转换为 ArrayList。

Element[] array = {new Element(1), new Element(2), new Element(3)};
ArrayList<Element>elementArray=new ArrayList();
for(int i=0;i<array.length;i++) {
elementArray.add(array[i]);
}

我们可以轻松地将数组转换为ArrayList.我们使用Collection接口的addAll()方法将内容从一个列表复制到另一个列表.

 Arraylist arr = new Arraylist();
arr.addAll(Arrays.asList(asset));
  • ArrayList的一个构造函数接受`?扩展Collection &lt;T&gt;参数,使对addAll的调用变得多余。

给定对象数组:

Element[] array = {new Element(1), new Element(2), new Element(3) , new Element(2)};

将数组转换为列表:

    List<Element> list = Arrays.stream(array).collect(Collectors.toList());

将数组转换为 ArrayList

    ArrayList<Element> arrayList = Arrays.stream(array)
.collect(Collectors.toCollection(ArrayList::new));

将数组转换为链表

    LinkedList<Element> linkedList = Arrays.stream(array)
.collect(Collectors.toCollection(LinkedList::new));

打印列表:

    list.forEach(element -> {
System.out.println(element.i);
});

输出

1

2

3


每个人都已经为您的问题提供了足够好的答案。现在,从所有建议中,您需要决定哪个适合您的要求。您需要了解两种类型的集合。一个是未修改的集合,另一个是允许您稍后修改对象的集合。

所以,在这里我将给出两个用例的简短示例。

  • List<Element> elementList = Arrays.asList(array)

  • List<Element> elementList = new ArrayList<Element>(Arrays.asList(array));

  • 请注意,您的“不可变集合”并不是真正不可变的 - `Arrays.asList` 返回的 `List` 只是原始数组的包装器,并允许通过 `get` 和 `set` 访问和修改单个项目。您可能应该澄清您的意思是“不添加或删除元素”而不是“不可变”,这意味着根本不改变。

Java 8 的 Arrays 类提供了一个 stream() 方法,该方法具有接受原始数组和对象数组的重载版本。

/**** Converting a Primitive 'int' Array to List ****/
int intArray[] = {1, 2, 3, 4, 5};
List<Integer> integerList1 = Arrays.stream(intArray).boxed().collect(Collectors.toList());
/**** 'IntStream.of' or 'Arrays.stream' Gives The Same Output ****/
List<Integer> integerList2 = IntStream.of(intArray).boxed().collect(Collectors.toList());
/**** Converting an 'Integer' Array to List ****/
Integer integerArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
List<Integer> integerList3 = Arrays.stream(integerArray).collect(Collectors.toList());

即使这个问题有很多写得很好的答案,我也会添加我的意见。

说你有 Element[] array = { new Element(1), new Element(2), new Element(3) };

可以通过以下方式创建新的ArrayList

ArrayList<Element> arraylist_1 = new ArrayList<>(Arrays.asList(array));
ArrayList<Element> arraylist_2 = new ArrayList<>(
Arrays.asList(new Element[] { new Element(1), new Element(2), new Element(3) }));
// Add through a collection
ArrayList<Element> arraylist_3 = new ArrayList<>();
Collections.addAll(arraylist_3, array);

而且它们很好地支持ArrayList的所有操作

arraylist_1.add(new Element(4)); // or remove(): Success
arraylist_2.add(new Element(4)); // or remove(): Success
arraylist_3.add(new Element(4)); // or remove(): Success

但是以下操作仅返回ArrayList的List视图,而不返回实际的ArrayList。

// Returns a List view of array and not actual ArrayList
List<Element> listView_1 = (List<Element>) Arrays.asList(array);
List<Element> listView_2 = Arrays.asList(array);
List<Element> listView_3 = Arrays.asList(new Element(1), new Element(2), new Element(3));

因此,当尝试进行一些ArrayList操作时,它们将给出错误。

listView_1.add(new Element(4)); // Error
listView_2.add(new Element(4)); // Error
listView_3.add(new Element(4)); // Error

有关数组链接的列表表示的更多信息。


最简单的方法是添加以下代码。尝试和测试。

String[] Array1={"one","two","three"};
ArrayList<String> s1= new ArrayList<String>(Arrays.asList(Array1));

您可以在Java 8中执行以下操作

ArrayList<Element> list = (ArrayList<Element>)Arrays.stream(array).collect(Collectors.toList());
  • 投反对票,因为那个演员看起来很危险。没有指定返回的列表类型实际上是一个 ArrayList,正如 javadoc 所述:“返回的列表的类型、可变性、可序列化性或线程安全性没有任何保证”

package package org.something.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Junk {
static <T> ArrayList<T>  arrToArrayList(T[] arr){
return Arrays.asList(arr)
.stream()
.collect(Collectors.toCollection(ArrayList::new));
}
public static void main(String[] args) {
String[] sArr = new String[]{"Hello", "cruel", "world"};
List<String> ret = arrToArrayList(sArr);
// Verify one can remove an item and print list to verify so
ret.remove(1);
ret.stream()
.forEach(System.out::println);
}
}

输出是...
Hello
world


下面的代码似乎是这样做的好方法。


以上是从数组创建ArrayList的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>