2012-07-25 3 views
43

У меня есть массив, который я хотел бы превратить в List, чтобы изменить содержимое массива.Создать измененный список из массива?

переполнение стека имеет много вопросов/ответов, которые касаются Arrays.asList() и как она обеспечивает только представление списка базового массива, и как пытается манипулировать результирующий список, как правило, бросаться UnsupportedOperationException также методы, используемые для управления списком (например, add(), remove() и т. Д.) Не реализованы реализацией списка, предоставленной Arrays.asList().

Но я не могу найти пример того, как превратить массив в изменяемый список. Я полагаю, что я могу пройти через массив и put() каждое значение в новый список, но мне интересно, существует ли какой-либо интерфейс для этого.

ответ

64

Один простой способ:

Foo[] array = ...; 
List<Foo> list = new ArrayList<Foo>(Arrays.asList(array)); 

Это создаст изменяемый список - но это будет копия исходного массива. Изменение списка будет не изменить массив. Вы можете скопировать его позже, конечно, используя toArray.

Если вы хотите создать изменяемый вид на массив, я считаю, что вам придется реализовать это самостоятельно.

+0

Это полностью приемлемый для моих нужд. Я в порядке с отбрасыванием исходного массива. – ericsoco

+1

Arrays.asList возвращает представление в массив, поддерживая поддерживаемые методы, которые не влияют на размер списка. –

+0

@ TimoWestkämper: Да, но я создаю новый ArrayList из этого представления. –

0
myNewArrayList = new ArrayList(
    Arrays.asList(
     (Object[])myArray))); 
+3

За исключением предпочтительно без использования необработанных типов ... –

11

И если вы используете Google коллекции API,

Lists.newArrayList(myArray) 
+0

Это самый краткий ответ. Благодарю. – eugene82

+0

Даже сам Guava рекомендует использовать либо новый ArrayList <> (Arrays.asList (...)) '- javadoc для метода подразумевает, что он станет устаревшим, потому что он недостаточно полезен. –

4

Если вы используете Eclipse Collections (ранее GS Collections), вы можете использовать FastList.newListWith(...) или FastList.wrapCopy(...).

Оба метода принимают varargs, поэтому вы можете создать массив inline или передать существующий массив.

MutableList<Integer> list1 = FastList.newListWith(1, 2, 3, 4); 

Integer[] array2 = {1, 2, 3, 4}; 
MutableList<Integer> list2 = FastList.newListWith(array2); 

Разница между двумя методами заключается в том, копируется ли массив. newListWith() не копирует массив и, следовательно, занимает постоянное время. Вы не должны использовать его, если знаете, что массив может быть изменен в другом месте.

Integer[] array2 = {1, 2, 3, 4}; 
MutableList<Integer> list2 = FastList.newListWith(array2); 
array2[1] = 5; 
Assert.assertEquals(FastList.newListWith(1, 5, 3, 4), list2); 

Integer[] array3 = {1, 2, 3, 4}; 
MutableList<Integer> list3 = FastList.wrapCopy(array3); 
array3[1] = 5; 
Assert.assertEquals(FastList.newListWith(1, 2, 3, 4), list3); 

Примечание: Я коммиттер для Eclipse, коллекций.

+1

Это хороший API-интерфейс для коллекций, который у вас есть. Первый, который я видел, может соблазнить меня от моих собственных реализаций ... Единственное, что, кажется, отсутствует, что я считаю полезным в целом, - это реализация отсортированного набора, поддерживаемая массивом (который, как я считаю, намного эффективнее, чем на основе дерева для данных, которые редко изменяются, или для наборов, которые могут часто меняться, но обычно содержат менее 10 или около того элементов). – Jules

0

Этот простой код, использующий API потока, включенный в Java 8 создает изменяемый список (или вид), содержащий элементы вашего массива:

Foo[] array = ...; 
List<Foo> list = Stream.of(array).collect(Collectors.toCollection(ArrayList::new)); 

Или, в равной степени действительный:

List<Foo> list = Arrays.stream(array).collect(Collectors.toCollection(ArrayList::new)); 
Смежные вопросы