Учитывая массив типа Element[]
:
Element[] array = {new Element(1), new Element(2), new Element(3)};
Как преобразовать этот массив в объект типа ArrayList<Element>
?
ArrayList<Element> arrayList = ???;
31 ответ
new ArrayList<>(Arrays.asList(array));
Код ниже кажется хорошим способом сделать это.
new ArrayList<T>(Arrays.asList(myArray));
Данный:
Element[] array = new Element[] { new Element(1), new Element(2), new Element(3) };
Самый простой ответ - сделать:
List<Element> list = Arrays.asList(array);
Это будет работать нормально. Но некоторые предостережения:
- Список, возвращаемый из asList, имеет фиксированный размер . Итак, если вы хотите иметь возможность добавлять или удалять элементы из возвращенного списка в вашем коде, вам нужно обернуть его в новый
ArrayList
. В противном случае вы получитеUnsupportedOperationException
. - Список, возвращаемый из
asList()
, поддерживается исходным массивом. Если вы измените исходный массив, список также будет изменен. Это может быть удивительно.
Arrays.asList()
создает java.util.Arrays.ArrayList
(статический вложенный класс в java.util.Arrays
), а не java.util.ArrayList
.
(старый поток, но всего 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 появилась с новым оператором Diamond.
Но это не единственная причина (и 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
, но на самом деле напрямую ссылается на переданный массив и делает его "сквозным" (изменения отражаются в массиве).
Он запрещает модификацию некоторых методов 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);
}
List
, возвращаемый Arrays.asList
, является изменяемым в том смысле, что вы все еще можете элементы set
- его просто нельзя изменить размер. Для неизменяемых списков без Guava вы можете указать Collections.unmodifiableList
.
Поскольку этот вопрос довольно старый, меня удивляет, что никто еще не предложил простейшую форму:
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));
Убедитесь, что myArray
того же типа, что и T
. Вы получите ошибку компилятора, если попытаетесь создать List<Integer>
, например, из массива int
.
Другой способ (хотя по сути эквивалентен решению 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
, Set
a> и Map
интерфейсы в Java 9 и новее.
Вероятно, вам нужен просто список, а не ArrayList. В этом случае вы можете просто сделать:
List<Element> arraylist = Arrays.asList(array);
set
), вы не можете изменить размер списка (не элементы add
или remove
)!
Если вы используете:
new ArrayList<T>(Arrays.asList(myArray));
Вы можете создать и заполнить два списка! Дважды заполнять большой список - это именно то, чего вы не хотите, потому что он будет создавать новый массив Object[]
каждый раз, когда необходимо увеличить емкость.
К счастью, реализация JDK выполняется быстро, а Arrays.asList(a[])
выполнен очень хорошо. Он создает своего рода ArrayList с именем Arrays.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
или гуаву. Но если это не подходит или вы этого не чувствуете, просто напишите вместо этого другую неэлегантную строку.
new ArrayList<T>(Arrays.asList(myArray));
, которую вы не поощряете использовать. Оба делают одно и то же и имеют одинаковую сложность.
new ArrayList<T>(Arrays.asList(myArray));
делает то же самое, он копирует asList
в ArrayList
...
В 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);
Начиная с Java 8, есть более простой способ преобразования:
import java.util.List;
import static java.util.stream.Collectors.toList;
public static <T> List<T> fromArray(T[] array) {
return Arrays.stream(array).collect(toList());
}
Вы можете конвертировать разными способами
List<Element> list = Arrays.asList(array);
List
list = new ArrayList ();
Collections.addAll (список, массив);Список Arraylist = новый Arraylist ();
list.addAll (Arrays.asList (массив));
Для получения дополнительных сведений см. 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
observableArrayList () Создает новый пустой наблюдаемый список, поддерживаемый arrayylist. observableArrayList (E ... items) Создает новый список наблюдаемых массивов с добавленными в него элементами.
Обновите Java 9
Также в Java 9 это немного проще:
List<String> list = List.of("element 1", "element 2", "element 3");
Вы также можете сделать это с потоком в Java 8.
List<Element> elements = Arrays.stream(array).collect(Collectors.toList());
Collectors.toList()
возвращает ArrayList
. Однако это может отличаться в будущих версиях на java. Если вам нужен определенный тип коллекции, используйте вместо этого Collectors.toCollection()
, где вы можете указать, какой именно тип коллекции вы хотите создать.
Если мы увидим определение метода
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
.На этот вопрос тоже может быть другой ответ.
Если вы увидите объявление для методаjava.util.Collections.addAll()
, вы получите что-то вроде этого:public static <T> boolean addAll(Collection<? super T> c, T... a);
Итак, этот код также полезен для этого
Collections.addAll(arraylist, array);
Если массив имеет примитивный тип, данные ответы не будут работать. Но начиная с Java 8 вы можете использовать:
int[] array = new int[5];
Arrays.stream(array).boxed().collect(Collectors.toList());
char
.
Другой простой способ - добавить все элементы из массива в новый список ArrayList, используя цикл for-each.
ArrayList<Element> list = new ArrayList<>();
for(Element e : array)
list.add(e);
Несмотря на то, что на этот вопрос есть много прекрасно написанных ответов, я добавлю свои комментарии.
Скажем, у вас есть 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, а не фактический 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));
Другое решение 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);
}
}
Вывод ...
Привет
Мир
Вы можете сделать это в java 8 следующим образом
ArrayList<Element> list = (ArrayList<Element>)Arrays.stream(array).collect(Collectors.toList());
ArrayList<String> list = Arrays.stream(array).collect(Collectors.toCollection(ArrayList::new));
Мы можем легко преобразовать массив в ArrayList
. Мы используем метод addAll()
интерфейса Collection для копирования содержимого из одного списка в другой.
Arraylist arr = new Arraylist();
arr.addAll(Arrays.asList(asset));
ArrayList
принимает аргумент ? extends Collection<T>
, что делает вызов addAll
избыточным.
Используйте следующий код для преобразования массива элементов в 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]);
}
Данный массив объектов:
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
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));
List
, возвращаемый Arrays.asList
, является просто оболочкой над исходным массивом и позволяет получать доступ к отдельным элементам и изменять их через get
и set
. Вам, вероятно, следует пояснить, что вы имеете в виду «не добавлять и не удалять элементы» вместо «неизменяемый», что означает не изменять вообще.
Класс Arrays в Java 8 предоставляет метод 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());
Вы также можете использовать полиморфизм для объявления ArrayList при вызове интерфейса Arrays следующим образом:
List<Element> arraylist = new ArrayList<Integer>(Arrays.asList(array));
Пример:
Integer[] array = {1}; // autoboxing
List<Integer> arraylist = new ArrayList<Integer>(Arrays.asList(array));
Это должно сработать как шарм.
Еще одно обновление, почти заканчивающееся в 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
.
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.
new ArrayList
также не нужен.List<ClassName> list = Arrays.asList(array)
Arrays.asList(array)
без передачи его в новый объектArrayList
исправит размер списка. Одна из наиболее распространенных причин использованияArrayList
- это возможность динамически изменять его размер, и ваше предложение предотвратит это.