Разница между массивами.asList (массив) и новый ArrayList (массивы.asList(массив))


в чем разница между

1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  //copy
2.List<Integer> list2 = Arrays.asList(ia);

здесь ia - это массив целых чисел.

я узнал, что некоторые операции не допускаются в list2. почему это так? как он хранится в памяти (ссылки / копия)?

когда я перетасовываю списки,list1 не влияет на исходный массив, но list2 делает. Но все же list2 несколько сбивает с толку.

как ArrayList передача в список отличается от создания нового ArrayList

list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
12 77

12 ответов:

  1. во-первых, давайте посмотрим, что это:

    Arrays.asList(ia)
    

    он принимает массив ia и создает оболочку, которая реализует List<Integer>, что делает исходный массив доступным в виде списка. Ничего не копируется и все, только один объект-оболочка создается. Операции в оболочке списка распространяются на исходный массив. Это означает, что при перетасовке оболочки списка исходный массив также перетасовывается, если вы перезаписываете элемент, он перезаписывается в исходный массив и т. д. Конечно, некоторые List операции не разрешены на оболочке, например добавление или удаление элементов из списка, вы можете только читать или перезаписывать элементы.

    обратите внимание, что список обертка не распространяется ArrayList - это другой вид объекта. ArrayLists имеют свой собственный, внутренний массив, в котором они хранят свои элементы и могут изменять размеры внутренних массивов и т. д. Оболочка не имеет собственного внутреннего массива, она только распространяет операции массив, данный ему.

  2. С другой стороны, если вы впоследствии создадите новый массив как

    new ArrayList<Integer>(Arrays.asList(ia))
    

    затем вы создаете новый ArrayList, который является полной, независимой копией оригинала. Хотя здесь вы создаете обертку с помощью Arrays.asList кроме того, он используется только во время строительства нового ArrayList и после этого собирается мусор. Структура этого нового ArrayList полностью не зависит от исходного массива. Он содержит те же элементы (как исходный массив, так и этот новый ArrayList ссылаться на те же целые числа в памяти), но он создает новый, внутренний массив, который содержит ссылки. Поэтому, когда вы перетасовываете его, добавляете, удаляете элементы и т. д., исходный массив не изменяется.

Ну это потому что ArrayList в результате Arrays.asList() не относится к типу java.util.ArrayList . Arrays.asList() создает ArrayList типа java.util.Arrays$ArrayList который не распространяется java.util.ArrayList но только расширяет java.util.AbstractList

List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  //copy

в этом случае list1 типа ArrayList.

List<Integer> list2 = Arrays.asList(ia);

здесь, список возвращается как List view, что означает, что он имеет только методы, прикрепленные к этому интерфейсу. Следовательно, почему некоторые методы не допускаются на list2.

ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));

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

ArrayList list1 = (ArrayList)Arrays.asList(ia);

Я довольно поздно здесь, в любом случае чувствовал, что объяснение со ссылками на doc было бы лучше для кого-то, кто ищет ответ.

  1. java.утиль.Массивы
  • это служебный класс с кучей статических методов для работы на данном массиве
  • asList является одним из таких статических методов, который принимает входной массив и возвращает объект java.утиль.Матрицы.ArrayList что является статический вложенный класс, который расширяет AbstractList, который inturn реализует интерфейс списка.
  • Так Массивы.asList (inarray) возвращает обертку списка вокруг входного массива, но эта обертка java.утиль.Матрицы.ArrayList, а не java.утиль.ArrayList и это относится к одному и тому же массиву, поэтому добавление большего количества элементов в список обернутого массива также повлияет на исходный, а также мы не можем изменить длину.
  1. java.утиль.ArrayList
  • ArrayList имеет кучу перегруженных конструкторов

    public ArrayList () - / / возвращает arraylist с емкостью по умолчанию 10

    public ArrayList (коллекция c)

    public ArrayList (int initialCapacity)

  • Итак, когда мы передаем массивы.asList возвращает объект т. е. List (AbstractList) во второй конструктор выше, он создаст новый динамический массив (этот размер массива увеличивается по мере добавления большего количества элементов, чем его емкость, а также новые элементы не будут влиять на исходный массив) неглубокое копирование исходного массива (мелкая копия означает, что он копирует только ссылки и не создает новый набор тех же объектов, что и в исходном массиве)

обратите внимание, что в Java 8 'ia' выше должно быть Integer [], а не int[]. Матрицы.asList() массива int возвращает список с одним элементом. При использовании фрагмента кода OP компилятор поймает проблему, но некоторые методы (например, коллекции.shuffle ()) будет молча не делать то, что вы ожидаете.

Arrays.asList()

этот метод возвращает свою собственную реализацию List.It принимает массив в качестве аргумента и строит методы и атрибуты поверх него, так как он не копирует какие-либо данные из массива, но использует исходный массив это вызывает изменение исходного массива при изменении списка, возвращаемого Arrays.asList() метод.

С другой стороны.
ArrayList(Arrays.asList()); является конструктором ArrayList класс, который принимает список в качестве аргумента и возвращает ArrayList это независимо от списка ie. Arrays.asList() в этом случае передается как аргумент. вот почему вы видите эти результаты;

    String names[] = new String[]{"Avinash","Amol","John","Peter"};
    java.util.List<String> namesList = Arrays.asList(names);
    or
    String names[] = new String[]{"Avinash","Amol","John","Peter"};
    java.util.List<String> temp = Arrays.asList(names);         

Above Statement adds the wrapper on the input array. So the methods like add & remove will not be applicable on list reference object 'namesList'.

If you try to add an element in the existing array/list then you will get "Exception in thread "main" java.lang.UnsupportedOperationException".

The above operation is readonly or viewonly. <br> We can not perform add or remove operation in list object.
But
String names[] = new String[]{"Avinash","Amol","John","Peter"};
java.util.ArrayList<String> list1 = new ArrayList<>(Arrays.asList(names));
or
String names[] = new String[]{"Avinash","Amol","John","Peter"};
java.util.List<String> listObject = Arrays.asList(names);
java.util.ArrayList<String> list1 = new ArrayList<>(listObject);

In above statement you have created a concrete instance of an ArrayList class and passed a list as a parameter.

In this case method add & remove will work properly as both methods are from ArrayList class so here we won't get any UnSupportedOperationException.    
Changes made in Arraylist object (method add or remove an element in/from an arraylist) will get not reflect in to original java.util.List object.

    String names[] = new String[] {
        "Avinash",
        "Amol",
        "John",
        "Peter"
    };

    java.util.List < String > listObject = Arrays.asList(names);
    java.util.ArrayList < String > list1 = new ArrayList < > (listObject);
    for (String string: list1) {
        System.out.print("   " + string);
    }
    list1.add("Alex"); //Added without any exception
    list1.remove("Avinash"); //Added without any exception will not make any changes in original list in this case temp object.


    for (String string: list1) {
        System.out.print("   " + string);
    }
    String existingNames[] = new String[] {
        "Avinash",
        "Amol",
        "John",
        "Peter"
    };
    java.util.List < String > namesList = Arrays.asList(names);
    namesList.add("Bob"); // UnsupportedOperationException occur
    namesList.remove("Avinash"); //UnsupportedOperationException

прежде всего класс массивов-это служебный класс, который содержит no. утилиты для работы с массивами (благодаря классу Arrays в противном случае нам пришлось бы создавать собственные методы для работы с объектами массива)

метод asList ():

  1. asList метод является одним из полезных методов Array класс, это статический метод вот почему мы можем назвать этот метод по его имени класса (например Arrays.asList(T...a))
  2. теперь вот поворот, пожалуйста, обратите внимание что этот метод не создает новый ArrayList "объект", он просто возвращает ссылку на список существующих Array объект (так что теперь после использования asList метод, две ссылки на существующие Array объект создается)
  3. и это причина, все методы, которые работают на List объект, может не работать на этом объекте массива с помощью List ссылка например, Arrayразмер s фиксирован по длине, поэтому вы, очевидно, не можете добавлять или удалять элементы из Array объект с помощью этого List ссылка (например list.add(10) или list.remove(10); иначе он бросит UnsupportedOperationException)
  4. любое изменение, которое вы делаете с помощью ссылки на список, будет отражено в выходе Arrays объект (как вы работаете на существующий объект массива с помощью списка ссылок)

в первом случае вы создаете новый Arraylist объект (во 2-м случае создается только ссылка на существующий объект массива, но не новый

1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  //copy
2.List<Integer> list2 = Arrays.asList(ia);

в строке 2, Arrays.asList(ia) возвращает a List ссылка на объект внутреннего класса, определенный в Arrays, который также называют ArrayList но является частным и только расширяет AbstractList. Это означает, что вернулся из Arrays.asList(ia) это объект класса, отличный от того, что вы получаете от new ArrayList<Integer>.

вы не можете использовать некоторые операции в строке 2, поскольку внутренний класс внутри Arrays не предоставляет эти методы.

взгляните на эту ссылку и посмотрите, что вы можете сделать с частным внутренним классом: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Arrays.java#Arrays.ArrayList

строка 1 создает новый ArrayList копирование элементов объекта из того, что вы получаете из строки 2. Так что вы можете делать все, что вы хотите, так как java.util.ArrayList предоставляет все эти методы.

package com.copy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class CopyArray {

    public static void main(String[] args) {
        List<Integer> list1, list2 = null;
        Integer[] intarr = { 3, 4, 2, 1 };
        list1 = new ArrayList<Integer>(Arrays.asList(intarr));
        list1.add(30);
        list2 = Arrays.asList(intarr);
        // list2.add(40); Here, we can't modify the existing list,because it's a wrapper
        System.out.println("List1");
        Iterator<Integer> itr1 = list1.iterator();
        while (itr1.hasNext()) {
            System.out.println(itr1.next());
        }
        System.out.println("List2");
        Iterator<Integer> itr2 = list2.iterator();
        while (itr2.hasNext()) {
            System.out.println(itr2.next());
        }
    }
}

многие люди уже ответили на механические детали, но стоит отметить: Это плохой выбор дизайна, Java.

Java asList метод документируется как " возвращает a фиксированного размера список...". Если вы берете его результат и звонить (допустим).add метод, он выдает UnsupportedOperationException. Это неинтуитивное поведение! Если метод возвращает List, стандартное ожидание заключается в том, что он возвращает объект, который поддерживает методы интерфейса List. Разработчик не должен запоминать , который из многочисленных util.List методы Lists, которые на самом деле не поддерживают все List методы.

если бы они назвали метод asImmutableList, имело бы смысл. Или если бы у них просто был метод, возвращающий фактическое List (и скопируйте резервный массив), это имело бы смысл. Они решили отдать предпочтение обеим runtime-performance и короткие имена, за счет нарушения как принципа наименьшего Удивление и хорошая практика избегания UnsupportedOperationException s.

(кроме того, дизайнеры могли бы сделать interface ImmutableList, чтобы избежать множества UnsupportedOperationException s.)

итог разница -

когда список создается без использования новых массивов оператора.метод asList () возвращает оболочку, что означает

1. вы можете выполнить операцию добавления / обновления.

2. изменения, сделанные в исходном массиве, также будут отражены в списке и наоборот.