133 votes

Différence entre Arrays.asList(array) et new ArrayList<Integer>(Arrays.asList(array))

Quelle est la différence entre

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

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

ia est un tableau d'entiers ?

Je suis venu à savoir que certaines opérations ne sont pas autorisées dans list2 . Pourquoi en est-il ainsi ? Comment est-elle stockée en mémoire (références / copie) ?

Quand je mélange les listes, list1 n'affecte pas le tableau original, mais list2 fait. Mais quand même list2 est quelque peu déroutant.

Comment ArrayList à la liste diffèrent de la création d'une nouvelle ArrayList ?

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

254voto

Petr Pudlák Points 25113
  1. Tout d'abord, voyons ce que cela fait :

    Arrays.asList(ia)

    Il prend un tableau ia et crée un wrapper qui implémente List<Integer> qui rend le tableau original disponible sous forme de liste. Rien n'est copié et tout, seulement un objet wrapper unique est créé. Les opérations sur l'enveloppe de la liste sont propagées au tableau d'origine. Cela signifie que si vous mélangez l'enveloppe de la liste, le tableau original est également mélangé, si vous écrasez un élément, il est écrasé dans le tableau original, etc. Bien sûr, certains List Les opérations ne sont pas autorisées sur le wrapper, comme l'ajout ou la suppression d'éléments de la liste, vous pouvez seulement lire ou écraser les éléments.

    Notez que le wrapper de liste n'étend pas ArrayList - c'est un autre type d'objet. ArrayList ont leur propre tableau interne, dans lequel ils stockent leurs éléments, et sont capables de redimensionner les tableaux internes, etc. Le wrapper n'a pas son propre tableau interne, il propage seulement les opérations dans le tableau qui lui est donné.

  2. D'autre part, si vous créez ensuite un nouveau tableau en tant que

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

    puis vous créez de nouveaux ArrayList qui est une copie complète et indépendante de l'original. Bien qu'ici vous créez le wrapper en utilisant Arrays.asList également, il n'est utilisé que pendant la construction de la nouvelle ArrayList et est ramassé après. La structure de ce nouveau ArrayList est complètement indépendant du tableau original. Il contient les mêmes éléments (le tableau original et le nouveau tableau ArrayList référencent les mêmes entiers en mémoire), mais il crée un nouveau tableau interne, qui contient les références. Ainsi, lorsque vous le mélangez, ajoutez ou supprimez des éléments, etc., le tableau d'origine reste inchangé.

31voto

Chris Points 3010

Eh bien, c'est parce que ArrayList résultant de Arrays.asList() n'est pas du type java.util.ArrayList .

Arrays.asList() crée un ArrayList de type java.util.Arrays$ArrayList qui ne s'étend pas java.util.ArrayList mais ne fait que s'étendre java.util.AbstractList .

9voto

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

Dans ce cas, list1 est de type ArrayList .

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

Ici, la liste est renvoyée sous la forme d'un List ce qui signifie qu'elle ne possède que les méthodes attachées à cette interface. C'est pourquoi certaines méthodes ne sont pas autorisées sur list2 .

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

Ici, vous sont créer un nouveau ArrayList . Vous lui passez simplement une valeur dans le constructeur. Ce n'est pas un exemple de casting. Dans le cas d'un casting, cela pourrait ressembler davantage à ceci :

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

4voto

John Frusciante Points 150

Une explication avec des références documentaires serait préférable pour quelqu'un qui cherche une réponse.

1. java.util.Arrays

  • C'est une classe utilitaire avec un tas de méthodes statiques pour opérer sur un tableau donné.
  • asList est une de ces méthodes statiques qui prend un tableau en entrée et renvoie un objet de type java.util.Arrays.ArrayList qui est une classe statique imbriquée qui étend AbstractList<E> qui à son tour implémente l'interface List.
  • Ainsi, Arrays.asList(inarray) renvoie une enveloppe de liste autour du tableau d'entrée, mais cette enveloppe est java.util.Arrays.ArrayList et non java.util.ArrayList et il fait référence au même tableau, donc ajouter plus d'éléments au tableau enveloppé par la liste affecterait aussi le tableau original et nous ne pouvons pas non plus changer la longueur.

2. java.util.ArrayList

  • ArrayList possède un grand nombre de constructeurs surchargés.

     public ArrayList() - // Returns arraylist with default capacity 10
    
     public ArrayList(Collection<? extends E> c)
    
     public ArrayList(int initialCapacity)
  • Ainsi, lorsque nous passons l'objet Arrays.asList retourné, c'est-à-dire List(AbstractList) au deuxième constructeur ci-dessus, il créera un nouveau tableau dynamique (la taille de ce tableau augmente lorsque nous ajoutons plus d'éléments que sa capacité et aussi les nouveaux éléments n'affecteront pas le tableau original) shallow copiant le tableau original ( copie superficielle signifie qu'il copie uniquement les références et ne crée pas un nouvel ensemble d'objets identiques à ceux du tableau d'origine.)

4voto

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

ou

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

L'instruction ci-dessus ajoute le wrapper sur le tableau d'entrée. Ainsi, les méthodes comme ajouter y supprimer ne sera pas applicable sur l'objet de référence de liste 'namesList'.

Si vous essayez d'ajouter un élément dans le tableau/la liste existant(e), vous obtiendrez "Exception in thread "main" java.lang.UnsupportedOperationException".

L'opération ci-dessus est en lecture seule ou en affichage seul.
Nous ne pouvons pas effectuer d'opération d'ajout ou de suppression dans l'objet liste.

Mais

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

ou

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

Dans la déclaration ci-dessus, vous avez créé une instance concrète de la classe ArrayList et passé une liste en tant que paramètre.

Dans ce cas, les méthodes ajouter y supprimer fonctionnera correctement car les deux méthodes sont issues de la classe ArrayList, donc ici nous n'obtiendrons pas d'UnSupportedOperationException. Les modifications apportées à l'objet ArrayList (méthode d'ajout ou de suppression d'un élément dans/depuis un ArrayList) ne seront pas reflétées dans l'objet original. objet java.util.List .

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X