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 ia
es 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, list1
no afecta a la matriz original, pero list2
sí. Pero todavía list2
es algo confuso.
En qué ArrayList
se 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
ia
y 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, algunasList
operaciones 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.ArrayList
Los 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 nuevoArrayList
y luego se recolecta la basura. La estructura de este nuevoArrayList
es completamente independiente de la matriz original. Contiene los mismos elementos (tanto la matriz original como esta nuevaArrayList
referencia 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 otraList
implementación según sea necesario, sin tener que reescribir mucho código.Bueno, esto se debe a que el
ArrayList
resultado deArrays.asList()
no es del tipojava.util.ArrayList
.Arrays.asList()
crea unArrayList
tipojava.util.Arrays$ArrayList
que no se extiendejava.util.ArrayList
sino que solo se extiendejava.util.AbstractList
fuente
En este caso,
list1
es de tipoArrayList
.Aquí, la lista se devuelve como una
List
vista, 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 ():
asList
El método es uno de los métodos de utilidad de laArray
clase, es un método estático, por eso podemos llamar a este método por su nombre de clase (comoArrays.asList(T...a)
)ArrayList
objeto, solo devuelve una referencia de lista alArray
objeto existente (por lo que ahora, después de usar elasList
método,Array
se crean dos referencias al objeto existente )List
objeto NO funcionen en este objeto Array usando unaList
referencia como, por ejemplo,Array
el tamaño de s tiene una longitud fija, por lo que obviamente no puede agregar o eliminar elementos delArray
objeto usando estoList
referencia (comolist.add(10)
olist.remove(10);
de lo contrario, arrojará UnsupportedOperationException)Array
del objeto s (ya que está operando en un objeto Array existente usando la referencia de lista)En el primer caso, está creando un nuevo
Arraylist
objeto (en el segundo caso, solo se crea una referencia al objeto Array existente pero no unArrayList
objeto nuevo ), por lo que ahora hay dos objetos diferentes, uno es unArray
objeto y otro es unArrayList
objeto 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 2Array
yArraylist
son 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
asList
método de Java está documentado como "Devuelve una lista de tamaño fijo ...". Si toma su resultado y llama (digamos) al.add
mé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.List
métodos creaList
s que en realidad no son compatibles con todos losList
mé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 evitarUnsupportedOperationException
s.(Además, los diseñadores podrían haber hecho un
interface ImmutableList
, para evitar una plétora deUnsupportedOperationException
s).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 deArrayList
clase que toma una lista como argumento y devuelve unaArrayList
que 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 unaList
referencia del objeto de clase interno definido dentroArrays
, que también se llamaArrayList
pero 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
Arrays
no 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
ArrayList
objeto copiando elementos de lo que obtiene de la línea 2. Entonces puede hacer lo que quiera, ya quejava.util.ArrayList
proporciona 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