从数组创建ArrayList

Ron Tuffin 3441 java arrays arraylist type-conversion

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

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

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

ArrayList<Element> arraylist = ???;

Tom.. 4449

new ArrayList<>(Arrays.asList(array))

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

Alex Miller.. 874

鉴于:

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). (30认同)
  • 包装新的ArrayList()将导致固定大小列表的所有元素被迭代并添加到新的ArrayList,因此是O(n). (22认同)
  • asList()返回的List的实现没有实现List的几个方法(如add(),remove(),clear()等等),这解释了UnsupportedOperationException.绝对是一个警告...... (8认同)
  • 当问题要求"ArrayList类的一个对象"时,我认为假设它引用的类是`java.util.ArrayList`是合理的.Arrays.asList实际上返回一个`java.util.Arrays.ArrayList`,它不是另一个类的`instanceof`.所以第三个警告是,如果你试图在需要上述内容的环境中使用它,它将无法工作. (8认同)
  • 两种操作的时间复杂度是多少?我的意思是使用和不使用明确的arraylist结构. (5认同)

haylem.. 338

(老线程,但只有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) \)). (26认同)

Tim Büthe.. 218

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

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")` (7认同)

Bill the Liz.. 198

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

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


Peter Tseng.. 92

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

Collections.addAll(arraylist, array);


Ali Dehghani.. 82

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 269Java Collections API 提供了一些便利工厂方法.这些一成不变的静态工厂方法被内置到List,SetMapJava中9以及更高的接口.


Kip.. 71

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

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

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

whyem.. 62

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

Nicolas Zozo.. 34

如果您使用:

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或番石榴.但如果它不适合,或者你感觉不适合,那就改写另一条不优雅的线.


MarekM.. 30

Java 9你可以使用:

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


nekperu15739.. 28

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

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

但是最好总是使用界面:

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


Bohdan.. 24

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


oxy_js.. 19

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

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

  2. List<Element> list = new ArrayList();
    Collections.addAll(list, array);

  3. Arraylist list = new Arraylist();
    list.addAll(Arrays.asList(array));

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


Abojemyeg.. 18

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

 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

observableArrayList()创建一个由arraylist支持的新的空可观察列表.observableArrayList(E ... items)创建一个新的可观察数组列表,其中添加了项目.

更新Java 9

在Java 9中它也有点简单:

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


Andrii Abram.. 17

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

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


小智.. 16

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

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

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

Vikrant Kash.. 11

  1. 如果我们看到Arrays.asList()方法的定义,你会得到这样的东西:

     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));
    

    注意:每个都new Element(int args)将被视为单个对象,可以作为一个传递var-args.

  2. 对于这个问题,可能还有另一个答案.
    如果您看到java.util.Collections.addAll()方法声明,您将得到如下内容:

    public static <T> boolean addAll(Collection<? super T> c, T... a);
    

    所以,这段代码也很有用

    Collections.addAll(arraylist, array);
    


spencer.sm.. 9

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

ArrayList<Element> list = new ArrayList<>();

for(Element e : array)
    list.add(e);


A1m.. 9

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

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


rashedcs.. 7

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

 Arraylist arr = new Arraylist();
 arr.addAll(Arrays.asList(asset));

  • ArrayList的一个构造函数接受`?扩展Collection &lt;T&gt;参数,使对addAll的调用变得多余。 (2认同)

Devendra Lat.. 5

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

说你有 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

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


小智.. 5

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

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


Adit A. Pill.. 5

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

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


Toothless Se.. 5

另一个Java8解决方案(我可能错过了很多答案)。如果是这样,我表歉意。这将创建一个ArrayList(与List相对),即可以删除元素

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


归档时间:

查看次数:

1437081 次

最近记录:

6 月,3 周 前