Quelle est la différence entre
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
2.List<Integer> list2 = Arrays.asList(ia);
où ia
est un tableau d'entiers.
J'ai appris que certaines opérations ne sont pas autorisées list2
. pourquoi en est-il ainsi? comment est-il stocké en mémoire (références / copie)?
Lorsque je mélange les listes, list1
n'affecte pas le tableau d'origine mais le list2
fait. Mais c'est encore list2
un peu déroutant.
En quoi la ArrayList
mise à niveau vers la liste diffère de la créationArrayList
list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
java
list
collections
Dineshkumar
la source
la source
Lists.newArrayList(ia)
fait une copie indépendante, comme la première option. C'est simplement plus général et mieux à regarder.Réponses:
Voyons d'abord ce que cela fait:
Il prend un tableau
ia
et crée un wrapper qui implémenteList<Integer>
, ce qui rend le tableau d'origine disponible sous forme de liste. Rien n'est copié et tout, un seul objet wrapper est créé. Les opérations sur le wrapper de liste sont propagées au tableau d'origine. Cela signifie que si vous mélangez le wrapper de liste, le tableau d'origine est également mélangé, si vous écrasez un élément, il est écrasé dans le tableau d'origine, etc. Bien sûr, certainesList
opérations ne sont pas autorisées sur le wrapper, comme l'ajout ou en supprimant des éléments de la liste, vous ne pouvez lire ou écraser que les éléments.Notez que le wrapper de liste ne s'étend pas
ArrayList
- c'est un autre type d'objet.ArrayList
s 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 uniquement les opérations sur le tableau qui lui est donné.D'autre part, si vous créez par la suite un nouveau tableau comme
puis vous créez un nouveau
ArrayList
, qui est une copie complète et indépendante de l'original. Bien qu'ici vous créez également le wrapper en utilisantArrays.asList
, il n'est utilisé que pendant la construction du nouveauArrayList
et est ensuite récupéré. La structure de ce nouveauArrayList
est complètement indépendante du tableau d'origine. Il contient les mêmes éléments (le tableau d'origine et cette nouvelleArrayList
référence 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, supprimez des éléments, etc., le tableau d'origine reste inchangé.la source
List<Integer>
pour vos types de variables (ou arguments de méthode, etc.). Cela rend votre code plus générique et vous pouvez facilement passer à une autreList
implémentation si nécessaire, sans avoir à réécrire beaucoup de code.Eh bien c'est parce que
ArrayList
résultant deArrays.asList()
n'est pas du typejava.util.ArrayList
.Arrays.asList()
crée unArrayList
typejava.util.Arrays$ArrayList
qui ne s'étend pasjava.util.ArrayList
mais qui ne s'étend quejava.util.AbstractList
la source
Dans ce cas,
list1
est de typeArrayList
.Ici, la liste est renvoyée sous forme de
List
vue, ce qui signifie qu'elle n'a que les méthodes attachées à cette interface. D'où pourquoi certaines méthodes ne sont pas autoriséeslist2
.Ici, vous créez un nouveau
ArrayList
. Vous lui passez simplement une valeur dans le constructeur. Ce n'est pas un exemple de casting. En casting, cela pourrait ressembler davantage à ceci:la source
Je suis assez tard ici, de toute façon senti qu'une explication avec des références doc serait meilleure pour quelqu'un qui cherche une réponse.
ArrayList a un tas de constructeurs surchargés
public ArrayList () - // retourne arraylist avec une capacité par défaut de 10
public ArrayList (Collection c)
public ArrayList (int initialCapacity)
Ainsi, lorsque nous passons l'objet retourné Arrays.asList, c'est-à-dire List (AbstractList) au deuxième constructeur ci-dessus, il créera un nouveau tableau dynamique (cette taille de tableau augmente à mesure que nous ajoutons plus d'éléments que sa capacité et les nouveaux éléments n'affecteront pas le tableau orignal ) copie superficielle du tableau d'origine ( copie superficielle signifie qu'elle copie uniquement les références et ne crée pas un nouvel ensemble des mêmes objets que dans le tableau orignal)
la source
ou
La déclaration ci-dessus ajoute le wrapper sur le tableau d'entrée. Ainsi, les méthodes comme ajouter et supprimer ne seront pas applicables sur l'objet de référence de liste 'namesList'.
Si vous essayez d'ajouter un élément dans le tableau / liste existant, vous obtiendrez "Exception dans le thread" main "java.lang.UnsupportedOperationException".
L'opération ci-dessus est en lecture seule ou en lecture seule.
Nous ne pouvons pas effectuer d'opération d'ajout ou de suppression dans l'objet de liste. Mais
ou
Dans l'instruction ci-dessus, vous avez créé une instance concrète d'une classe ArrayList et passé une liste en tant que paramètre.
Dans ce cas, la méthode add & remove fonctionnera correctement car les deux méthodes proviennent de la classe ArrayList, donc ici, nous n'obtiendrons pas d'exception UnSupportedOperationException.
Les modifications apportées à l'objet Arraylist (méthode d'ajout ou de suppression d'un élément dans / d'une arraylist) ne seront pas reflétées dans l'objet java.util.List d'origine.
la source
Tout d'abord, la classe Arrays est une classe utilitaire qui ne contient aucun fichier. de méthodes utilitaires pour opérer sur des tableaux (grâce à la classe Arrays sinon nous aurions dû créer nos propres méthodes pour agir sur les objets Array)
Méthode asList ():
asList
method est l'une des méthodes utilitaires de laArray
classe, c'est une méthode statique c'est pourquoi nous pouvons appeler cette méthode par son nom de classe (commeArrays.asList(T...a)
)ArrayList
objet, elle renvoie simplement une référence List à unArray
objet existant (donc maintenant, après l'utilisation de laasList
méthode, deux références à unArray
objet existant sont créées)List
objet, peuvent NE PAS fonctionner sur cet objet Array en utilisant uneList
référence comme par exemple, laArray
taille de s est de longueur fixe, donc vous ne pouvez évidemment pas ajouter ou supprimer des éléments de l'Array
objet en utilisant cetteList
référence (commelist.add(10)
oulist.remove(10);
sinon, il lancera une exception UnsupportedOperationException)Array
objet s (lorsque vous travaillez sur un objet Array existant en utilisant une référence de liste)Dans le premier cas, vous créez un nouvel
Arraylist
objet (dans le 2ème cas, seule la référence à un objet Array existant est créée mais pas un nouvelArrayList
objet), donc maintenant il y a deux objets différents, l'un est unArray
objet et un autre est unArrayList
objet et aucune connexion entre eux (donc change dans un objet ne sera pas reflété / affecté dans un autre objet (c'est-à-dire dans le cas 2Array
etArraylist
sont deux objets différents)cas 1:
cas 2:
la source
Beaucoup de gens ont déjà répondu aux détails mécaniques, mais cela vaut la peine de noter: il s'agit d'un mauvais choix de conception, de Java.
La
asList
méthode Java est documentée comme "Renvoie une liste de taille fixe ...". Si vous prenez son résultat et appelez (disons) la.add
méthode, il lance un fichierUnsupportedOperationException
. C'est un comportement peu intuitif! Si une méthode dit qu'elle renvoie aList
, l'attente standard est qu'elle renvoie un objet qui prend en charge les méthodes d'interfaceList
. Un développeur ne devrait pas avoir à mémoriser laquelle des innombrablesutil.List
méthodes crée desList
s qui ne prennent pas en charge toutes lesList
méthodes.S'ils avaient nommé la méthode
asImmutableList
, cela aurait du sens. Ou s'ils avaient juste la méthode renvoyer un réelList
(et copier le tableau de sauvegarde), cela aurait du sens. Ils ont décidé de favoriser à la fois les performances d'exécution et les noms courts, au détriment de la violation à la fois du principe de la moindre surprise et de la bonne pratique d'éviter l'UnsupportedOperationException
art.(En outre, les concepteurs auraient pu en faire un
interface ImmutableList
, pour éviter une pléthore deUnsupportedOperationException
s.)la source
Notez que, dans Java 8, «ia» ci-dessus doit être Integer [] et non int []. Arrays.asList () d'un tableau int renvoie une liste avec un seul élément. Lors de l'utilisation de l'extrait de code d'OP, le compilateur détecte le problème, mais certaines méthodes (par exemple Collections.shuffle ()) échouent silencieusement à faire ce que vous attendez.
la source
la source
Arrays.asList()
Cette méthode retourne sa propre implémentation de List.Il prend un tableau comme argument et construit des méthodes et des attributs par-dessus, car il ne copie aucune donnée d'un tableau mais utilise le tableau d'origine, cela provoque une altération du tableau d'origine lorsque vous modifiez liste renvoyée par la
Arrays.asList()
méthode.d'autre part.
ArrayList(Arrays.asList());
est un constructeur deArrayList
classe qui prend une liste comme argument et retourne unArrayList
qui est indépendant de la liste ie.Arrays.asList()
dans ce cas passé en argument. c'est pourquoi vous voyez ces résultats;la source
À la ligne 2,
Arrays.asList(ia)
renvoie uneList
référence d'objet de classe interne défini dansArrays
, qui est également appeléArrayList
mais qui est privé et ne s'étend queAbstractList
. Cela signifie que ce qui est renvoyéArrays.asList(ia)
est un objet de classe différent de ce que vous obteneznew ArrayList<Integer>
.Vous ne pouvez pas utiliser certaines opérations sur la ligne 2 car la classe privée interne
Arrays
ne fournit pas ces méthodes.Jetez un œil à ce lien et voyez ce que vous pouvez faire avec la classe interne privée: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ Arrays.java # Arrays.ArrayList
La ligne 1 crée un nouvel
ArrayList
objet en copiant les éléments de ce que vous obtenez de la ligne 2. Ainsi, vous pouvez faire ce que vous voulez puisquejava.util.ArrayList
fournit toutes ces méthodes.la source
Résumé de la différence -
lorsque la liste est créée sans utiliser le nouvel opérateur de la méthode Arrays.asList (), elle renvoie Wrapper ce qui signifie
1. vous pouvez effectuer une opération d'ajout / de mise à jour.
2. les modifications effectuées dans le tableau d'origine seront également reflétées dans List et vice versa.
la source
En réponse à quelques commentaires posant des questions sur le comportement de Arrays.asList () depuis Java 8:
la source