Вопрос: Создать ArrayList из массива


У меня есть массив, который инициализируется следующим образом:

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

Я хотел бы преобразовать этот массив в объект класса ArrayList.

ArrayList<Element> arraylist = ???;

2914


источник


Ответы:


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

3902



Данный:

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()подкрепляется исходным массивом. Если вы измените исходный массив, список также будет изменен. Это может быть удивительно.

762



(старая нить, но всего 2 цента, поскольку никто не упоминает 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 заводские методы разрешить типы, которые следует вывести большую часть времени. Тем не менее, этот аргумент содержит меньше воды, поскольку Java 7 прибыла с новым оператором бриллианта.

Но это не единственная причина (и Java 7 не везде): синтаксис сокращений также очень удобен, а инициализаторы методов, как видно выше, позволяют писать более выразительный код. Вы делаете в одном вызове Guava то, что занимает 2 с текущей коллекцией Java.


Если вы не можете ...

Для неизменяемого списка

Использовать 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но на самом деле напрямую ссылается на переданный массив и заставляет его «писать» (изменения отражены в массиве).

Он запрещает модификации через некоторые из ListAPI путем простого расширения 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);
}

288



Поскольку этот вопрос довольно старый, меня удивляет, что никто не предложил простейшую форму:

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

Начиная с Java 5, Arrays.asList()принимает параметр varargs, и вам не нужно явно строить массив.


198



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

Make sure that myArray is the same type as T. You'll get a compiler error if you try to create a List<Integer> from an array of int, for example.


170



Another way (although essentially equivalent to the new ArrayList(Arrays.asList(array)) solution performance-wise:

Collections.addAll(arraylist, array);

74



You probably just need a List, not an ArrayList. In that case you can just do:

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

60



Java 9

In Java 9, you can use List.of static factory method in order to create a List literal. Something like the following:

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

This would return an immutable list containing three elements. If you want a mutable list, pass that list to the ArrayList constructor:

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

JEP 269: Convenience Factory Methods for Collections

JEP 269 provides some convenience factory methods for Collections API. This factory methods are not in current Java version, which is 8, but are planned for Java 9 release. You can try out this feature using JDK 9 Early Access.


55



Another update, almost ending year 2014, you can do it with Java 8 too:

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

A few characters would be saved, if this could be just a List

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

53



To convert an array to an ArrayList, developers often do this:

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

Arrays.asList() will return an ArrayList which is a private static class inside Arrays, it is not the java.util.ArrayList class. The java.util.Arrays.ArrayList class has set(), get(), contains() methods, but does not have any methods for adding elements, so its size is fixed. To create a real ArrayList, you must do:

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

The constructor of ArrayList can accept a Collection type, which is also a super type for java.util.Arrays.ArrayList


46



If you use :

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

you may create and fill two lists ! Filling twice a big list is exactly what you don't want to do because it will create another Object[] array each time the capacity needs to be extended.

Fortunately the JDK implementation is fast and Arrays.asList(a[]) is very well done. It create a kind of ArrayList named Arrays.ArrayList where the Object[] data points directly to the array.

// 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
    }
    ....
}

The dangerous side is that if you change the initial array, you change the List ! Are you sure you want that ? Maybe yes, maybe not.

If not, the most understandable way is to do this :

ArrayList<Element> list = new ArrayList<Element>(myArray.length); // you know the initial capacity
for (Element element : myArray) {
    list.add(element);
}

Or as said @glglgl, you can create another independant ArrayList with :

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

I love to use Collections, Arrays, or Guava. But if it don't fit, or you don't feel it, just write another inelegant line instead.


28