Cuál es la diferencia entre
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
2.List<Integer> list2 = Arrays.asList(ia);
donde iaes una matriz de enteros.
Llegué a saber que algunas operaciones no están permitidas list2. ¿por que es esto entonces? ¿Cómo se almacena en la memoria (referencias / copia)?
Cuando mezclo las listas, list1no afecta a la matriz original, pero list2sí. Pero todavía list2es algo confuso.
En qué ArrayListse diferencia de la creación de nuevasArrayList
list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
java
list
collections
Dineshkumar
fuente
fuente

Lists.newArrayList(ia)realiza una copia independiente, al igual que la primera opción. Es simplemente más general y mejor de mirar.Respuestas:
Primero, veamos qué hace esto:
Toma una matriz
iay crea un contenedor que implementaList<Integer>, lo que hace que la matriz original esté disponible como una lista. No se copia nada y todo, solo se crea un único objeto contenedor. Las operaciones en el contenedor de la lista se propagan a la matriz original. Esto significa que si mezcla la envoltura de la lista, la matriz original también se mezcla, si sobrescribe un elemento, se sobrescribe en la matriz original, etc. Por supuesto, algunasListoperaciones no están permitidas en la envoltura, como agregar o eliminando elementos de la lista, solo puede leer o sobrescribir los elementos.Tenga en cuenta que la envoltura de la lista no se extiende
ArrayList, es un tipo diferente de objeto.ArrayListLos s tienen su propia matriz interna, en la que almacenan sus elementos, y pueden cambiar el tamaño de las matrices internas, etc. El contenedor no tiene su propia matriz interna, solo propaga operaciones a la matriz que se le ha asignado.Por otro lado, si posteriormente crea una nueva matriz como
luego crea una nueva
ArrayList, que es una copia completa e independiente de la original. Aunque aquí también crea el contenedor usandoArrays.asList, solo se usa durante la construcción del nuevoArrayListy luego se recolecta la basura. La estructura de este nuevoArrayListes completamente independiente de la matriz original. Contiene los mismos elementos (tanto la matriz original como esta nuevaArrayListreferencia tienen los mismos enteros en la memoria), pero crea una nueva matriz interna que contiene las referencias. Entonces, cuando lo mezcla, agrega, elimina elementos, etc., la matriz original no cambia.fuente
List<Integer>para sus tipos de variables (o argumentos de método, etc.). Esto hace que su código sea más genérico y puede cambiar fácilmente a otraListimplementación según sea necesario, sin tener que reescribir mucho código.Bueno, esto se debe a que el
ArrayListresultado deArrays.asList()no es del tipojava.util.ArrayList.Arrays.asList()crea unArrayListtipojava.util.Arrays$ArrayListque no se extiendejava.util.ArrayListsino que solo se extiendejava.util.AbstractListfuente
En este caso,
list1es de tipoArrayList.Aquí, la lista se devuelve como una
Listvista, lo que significa que solo tiene los métodos adjuntos a esa interfaz. De ahí por qué algunos métodos no están permitidoslist2.Aquí, ESTÁS creando un nuevo
ArrayList. Simplemente le está pasando un valor en el constructor. Este no es un ejemplo de casting. En el casting, podría verse más como esto:fuente
Llego bastante tarde aquí, de todos modos sentí que una explicación con referencias de documentos sería mejor para alguien que busca una respuesta.
ArrayList tiene un montón de constructores sobrecargados
public ArrayList () - // devuelve lista de matrices con capacidad predeterminada 10
public ArrayList (Colección c)
public ArrayList (int initialCapacity)
Entonces, cuando pasamos el objeto devuelto Arrays.asList, es decir, List (AbstractList) al segundo constructor anterior, creará una nueva matriz dinámica (este tamaño de matriz aumenta a medida que agregamos más elementos que su capacidad y también los nuevos elementos no afectarán la matriz original ) copia superficial de la matriz original ( copia superficial significa que copia solo las referencias y no crea un nuevo conjunto de los mismos objetos que en la matriz original)
fuente
o
La declaración anterior agrega el contenedor en la matriz de entrada. Por lo tanto, los métodos como agregar y eliminar no serán aplicables en el objeto de referencia de la lista 'namesList'.
Si intenta agregar un elemento en la matriz / lista existente, obtendrá "Excepción en el hilo" principal "java.lang.UnsupportedOperationException".
La operación anterior es de solo lectura o solo visualización.
No podemos realizar la operación de agregar o quitar en el objeto de lista. Pero
o
En la declaración anterior, ha creado una instancia concreta de una clase ArrayList y ha pasado una lista como parámetro.
En este caso, el método add & remove funcionará correctamente ya que ambos métodos son de la clase ArrayList, por lo que aquí no obtendremos ninguna UnSupportedOperationException.
Los cambios realizados en el objeto Arraylist (método para agregar o eliminar un elemento en / de una lista de arreglos) no se reflejarán en el objeto java.util.List original.
fuente
En primer lugar, la clase Arrays es una clase de utilidad que no contiene. de métodos de utilidad para operar en Arrays (gracias a la clase Arrays, de lo contrario, habríamos necesitado crear nuestros propios métodos para actuar sobre objetos Array)
método asList ():
asListEl método es uno de los métodos de utilidad de laArrayclase, es un método estático, por eso podemos llamar a este método por su nombre de clase (comoArrays.asList(T...a))ArrayListobjeto, solo devuelve una referencia de lista alArrayobjeto existente (por lo que ahora, después de usar elasListmétodo,Arrayse crean dos referencias al objeto existente )Listobjeto NO funcionen en este objeto Array usando unaListreferencia como, por ejemplo,Arrayel tamaño de s tiene una longitud fija, por lo que obviamente no puede agregar o eliminar elementos delArrayobjeto usando estoListreferencia (comolist.add(10)olist.remove(10);de lo contrario, arrojará UnsupportedOperationException)Arraydel objeto s (ya que está operando en un objeto Array existente usando la referencia de lista)En el primer caso, está creando un nuevo
Arraylistobjeto (en el segundo caso, solo se crea una referencia al objeto Array existente pero no unArrayListobjeto nuevo ), por lo que ahora hay dos objetos diferentes, uno es unArrayobjeto y otro es unArrayListobjeto y no hay conexión entre ellos (por lo que cambia en un objeto no se reflejará / afectará en otro objeto (es decir, en el caso 2ArrayyArraylistson dos objetos diferentes)caso 1:
caso 2:
fuente
Mucha gente ya ha respondido a los detalles mecánicos, pero vale la pena señalar: esta es una mala elección de diseño de Java.
El
asListmétodo de Java está documentado como "Devuelve una lista de tamaño fijo ...". Si toma su resultado y llama (digamos) al.addmétodo, arroja unUnsupportedOperationException. ¡Este es un comportamiento poco intuitivo! Si un método dice que devuelve unList, la expectativa estándar es que devuelva un objeto que admita los métodos de interfazList. Un desarrollador no debería tener que memorizar cuál de los innumerablesutil.Listmétodos creaLists que en realidad no son compatibles con todos losListmétodos.Si hubieran nombrado el método
asImmutableList, tendría sentido. O si solo tuvieran el método devolviendo un valor realList(y copiando la matriz de respaldo), tendría sentido. Decidieron favorecer tanto el rendimiento en tiempo de ejecución como los nombres cortos, a expensas de violar tanto el Principio de la menor sorpresa como la buena práctica de OO de evitarUnsupportedOperationExceptions.(Además, los diseñadores podrían haber hecho un
interface ImmutableList, para evitar una plétora deUnsupportedOperationExceptions).fuente
Tenga en cuenta que, en Java 8, 'ia' anterior debe ser Integer [] y no int []. Arrays.asList () de una matriz int devuelve una lista con un solo elemento. Cuando se usa el fragmento de código de OP, el compilador detectará el problema, pero algunos métodos (por ejemplo, Collections.shuffle ()) fallarán silenciosamente en hacer lo que espera.
fuente
fuente
Arrays.asList()este método devuelve su propia implementación de List. Toma una matriz como argumento y construye métodos y atributos encima de ella, ya que no está copiando ningún dato de una matriz, pero usando la matriz original, esto causa alteración en la matriz original cuando modificas lista devuelta por el
Arrays.asList()método.por otra parte.
ArrayList(Arrays.asList());es un constructor deArrayListclase que toma una lista como argumento y devuelve unaArrayListque es independiente de la lista, es decir.Arrays.asList()en este caso pasó como argumento. es por eso que ves estos resultados;fuente
En la línea 2,
Arrays.asList(ia)devuelve unaListreferencia del objeto de clase interno definido dentroArrays, que también se llamaArrayListpero es privado y solo se extiendeAbstractList. Esto significa que lo que regresaArrays.asList(ia)es un objeto de clase diferente de lo que obtienenew ArrayList<Integer>.No puede usar algunas operaciones en la línea 2 porque la clase privada interna dentro
Arraysno proporciona esos métodos.Eche un vistazo a este enlace y vea lo que puede hacer con la clase interna privada: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ Arrays.java # Arrays.ArrayList
La línea 1 crea un nuevo
ArrayListobjeto copiando elementos de lo que obtiene de la línea 2. Entonces puede hacer lo que quiera, ya quejava.util.ArrayListproporciona todos esos métodos.fuente
Resumen de la diferencia -
cuando la lista se crea sin usar el nuevo método Arrays.asList () del operador, devuelve Wrapper, lo que significa
1. puede realizar la operación de agregar / actualizar.
2. Los cambios realizados en la matriz original también se reflejarán en la Lista y viceversa.
fuente
En respuesta a algunos comentarios que hacen preguntas sobre el comportamiento de Arrays.asList () desde Java 8:
fuente