提问



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


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


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


ArrayList<Element> arraylist = ???;

最佳参考


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

其它参考1


鉴于:


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()返回的列表由原始数组支持。如果修改原始数组,则也会修改列表。这可能是令人惊讶的。


其它参考2


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


如果可以,请使用番石榴



值得指出的是番石榴方式,这极大地简化了这些恶作剧:


用法



对于不可变列表



使用ImmutableList类及其of()copyOf()工厂方法(元素不能为空):[113] [114] [[[115]


List<String> il = ImmutableList.of("string", "elements");  // from varargs
List<String> il = ImmutableList.copyOf(aStringArray);      // from array


对于可变列表



使用Lists类及其newArrayList()工厂方法:[116] [117]


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[118]


为什么选择番石榴?



主要的吸引力可能是减少由于仿制品的类型安全造成的混乱,因为使用番石榴工厂方法允许在大多数时间推断类型。然而,自Java 7与新的钻石操作员一起到达以来,这个论点含有较少的水。[119] [120]


但这不是唯一的原因(并且Java 7还没有到处):简写语法也非常方便,如上所述,方法初始化器允许编写更具表现力的代码。你在一个Guava调用中执行当前Java集合需要2。





如果你不能......



对于不可变列表



使用JDKArrays类及其asList()工厂方法,用Collections.unmodifiableList()包裹:[121] [122] [123]


List<String> l1 = Collections.unmodifiableList(Arrays.asList(anArrayOfElements));
List<String> l2 = Collections.unmodifiableList(Arrays.asList("element1", "element2"));


请注意,asList()的返回类型是使用具体ArrayList实现的List,但是它不是 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);
}

其它参考3


由于这个问题已经很老了,令我惊讶的是没有人提出最简单的形式:


List<Element> arraylist = Arrays.asList(new Element(1), new Element(2), new Element(3));


从Java 5开始,Arrays.asList()采用varargs参数,您不必显式构造数组。

其它参考4


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


确保myArrayT的类型相同。例如,如果您尝试从int的数组创建List<Integer>,则会出现编译器错误。

其它参考5


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


Collections.addAll(arraylist, array);

其它参考6


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


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

其它参考7


Java 9



在Java 9中,您可以使用List.of静态工厂方法来创建List文字。如下所示:[124] [125]


List<Element> elements = List.of(new Element(1), new Element(2), new Element(3));


这将返回包含三个元素的 不可变 列表。如果您需要 可变 列表,请将该列表传递给ArrayList构造函数:[126]


new ArrayList<>(List.of(// elements vararg))





JEP 269:收集的便利工厂方法



JEP 269为Java Collections API提供了一些方便的工厂方法。这些不可变的静态工厂方法内置于Java 9及更高版本的ListSetMap接口中。[127] [128] [129] [[[130] [131]

其它参考8


另一个更新,即将结束的2014年,您也可以使用Java 8:


ArrayList<Element> arrayList = Stream.of(myArray).collect(Collectors.toCollection(ArrayList::new));


如果这可能只是一个List,则会保存一些字符


List<Element> list = Stream.of(myArray).collect(Collectors.toList());

其它参考9


要将数组转换为ArrayList,开发人员通常会这样做:


List<String> list = Arrays.asList(arr);// this is wrong way..


Arrays.asList()将返回一个private static class inside Arrays的ArrayList,它不是java.util.ArrayList类。 The java.util.Arrays.ArrayList类有set(), get(), contains()方法,但没有任何添加元素的方法,所以它的大小是固定的。
要创建一个真正的ArrayList,您必须:


ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));


ArrayList的构造函数可以接受集合类型,它也是java.util.Arrays.ArrayList的超类型

其它参考10


如果您使用:


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


我喜欢使用CollectionsArrays或番石榴。但如果它不合适,或者你感觉不到,那就改写另一条不优雅的路线吧。

其它参考11


Java 9中你可以使用:


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

其它参考12


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


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


然而,最好总是使用界面:


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

其它参考13


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

其它参考14


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



  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 [132]

其它参考15


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


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

其它参考16


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


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

其它参考17



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


其它参考18


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


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

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

其它参考19


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


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


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


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


对于Java SE,您可以尝试


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


这是根据Oracle Docs [133]



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


其它参考20


鉴于:


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


使用:


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

其它参考21


虽然这个问题有很多完美的书面答案,但我会添加我的输入。


说你有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操作时,它们会出错


[[43.]]

更多关于数组链接的List表示。

其它参考22


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


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

其它参考23


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


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

其它参考24


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


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

其它参考25



  另一个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);
    }
}


输出是......

你好

世界

其它参考26


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


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



  • 不可变集合创建::当您不想在创建后修改集合对象时


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

  • 可变集合创建::当您想要在创建后修改创建的集合对象时。


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


其它参考27


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


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

其它参考28


 Element[] array = {new Element(1), new Element(2), new Element(3)};
 List<Element> elements=Arrays.asList(array);

其它参考29


您可以使用Cactoos创建ArrayList(我是其中一个开发人员):[135]


List<String> names = new StickyList<>(
  "Scott Fitzgerald", "Fyodor Dostoyevsky"
);


无法保证对象实际上属于类ArrayList。如果您需要该保证,请执行以下操作:


ArrayList<String> list = new ArrayList<>(
  new StickyList<>(
    "Scott Fitzgerald", "Fyodor Dostoyevsky"
  )
);