array - aslist java ejemplo
Diferencia entre Arrays.asList(array) y ArrayList<Integer>(Arrays.asList(array)) (11)
Primero, veamos qué hace esto:
Arrays.asList(ia)
Toma una matriz
ia
y crea una envoltura que implementa laList<Integer>
, que hace que la matriz original esté disponible como una lista. No se copia nada y todo, solo se crea un único objeto envoltorio. Las operaciones en el contenedor de lista se propagan a la matriz original. Esto significa que si mezcla el contenedor de listas, el conjunto original también se mezcla, si sobrescribe un elemento, se sobrescribe en el conjunto original, etc. Por supuesto, algunas operaciones de listas no están permitidas en el contenedor, como agregar o eliminando elementos de la lista, solo puede leer o sobrescribir los elementos.Tenga en cuenta que el contenedor de listas no extiende
ArrayList
, es un tipo diferente de objeto.ArrayList
tiene su propia matriz interna, en la cual almacenan sus elementos, y pueden cambiar el tamaño de las matrices internas, etc. La envoltura no tiene su propia matriz interna, solo propaga las operaciones a la matriz que se le ha asignado.Por otro lado, si posteriormente crea una nueva matriz como
new ArrayList<Integer>(Arrays.asList(ia))
luego creas una nueva
ArrayList
, que es una copia completa e independiente de la original. Aunque aquí también crea el contenedor utilizandoArrays.asList
, solo se usa durante la construcción del nuevoArrayList
y luego se recoge basura. La estructura de esta nuevaArrayList
es completamente independiente de la matriz original. Contiene los mismos elementos (tanto el conjunto original como este nuevoArrayList
referencia a los mismos números enteros en la memoria), pero crea un nuevo conjunto interno que contiene las referencias. Entonces, cuando lo mezcla, agrega, elimina elementos, etc., la matriz original no cambia.
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 en list2
. ¿por que es esto entonces? ¿Cómo se almacena en la memoria (referencias / copia)?
Cuando barajo las listas, list1
no afecta a la matriz original, pero list2
sí. Pero aún list2
es algo confuso.
Cómo ArrayList
se actualiza a la lista difiere de la creación de ArrayList
nueva
list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
Bueno, esto se debe a que ArrayList
resultante de Arrays.asList()
no es del tipo java.util.ArrayList
. Arrays.asList()
crea una ArrayList
de tipo java.util.Arrays$ArrayList
que no extiende java.util.ArrayList
pero solo extiende java.util.AbstractList
En primer lugar, la clase Arrays es una clase de utilidad que contiene no. de los métodos de utilidad para operar en Arrays (gracias a la clase Array, de lo contrario, habríamos necesitado crear nuestros propios métodos para actuar sobre los objetos Array)
Método asList ():
-
asList
métodoasList
es uno de los métodos de utilidad de la claseArray
, es un método estático por lo que podemos llamar a este método por su nombre de clase (comoArrays.asList(T...a)
) - Ahora este es el giro, tenga en cuenta que este método no crea un nuevo objeto
ArrayList
, simplemente devuelve una referencia de lista al objetoArray
existente (por lo que ahora, después de usar el métodoasList
, seasList
dos referencias al objetoArray
existente) - y esta es la razón, todos los métodos que operan en el objeto
List
, NO pueden funcionar en este objeto Array utilizando la referencia deList
como, por ejemplo, el tamaño delArray
está fijo en longitud, por lo tanto, obviamente no puede agregar o quitar elementos del objetoArray
usando esteList
referencia (comolist.add(10)
olist.remove(10);
contrario arrojará UnsupportedOperationException) - cualquier cambio que esté haciendo usando la referencia de lista se reflejará al salir del objeto
Array
(ya que está operando en un objeto Array existente usando la referencia de la lista)
En el primer caso está creando un nuevo objeto Arraylist
(en el segundo caso solo se crea una referencia al objeto Array existente pero no un nuevo objeto ArrayList
), de modo que ahora hay dos objetos diferentes: uno es Array
y otro es ArrayList
y no hay conexión entre ellos (por lo que los cambios en un objeto no se reflejarán / afectarán en otro objeto (es decir, en el caso 2 Array
y Arraylist
son dos objetos diferentes)
caso 1:
Integer [] ia = {1,2,3,4};
System.out.println("Array : "+Arrays.toString(ia));
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); // new ArrayList object is created , no connection between existing Array Object
list1.add(5);
list1.add(6);
list1.remove(0);
list1.remove(0);
System.out.println("list1 : "+list1);
System.out.println("Array : "+Arrays.toString(ia));
caso 2:
Integer [] ia = {1,2,3,4};
System.out.println("Array : "+Arrays.toString(ia));
List<Integer> list2 = Arrays.asList(ia); // creates only a (new ) List reference to existing Array object (and NOT a new ArrayList Object)
// list2.add(5); // it will throw java.lang.UnsupportedOperationException - invalid operation (as Array size is fixed)
list2.set(0,10); // making changes in existing Array object using List reference - valid
list2.set(1,11);
ia[2]=12; // making changes in existing Array object using Array reference - valid
System.out.println("list2 : "+list2);
System.out.println("Array : "+Arrays.toString(ia));
Llegué bastante tarde aquí, de todos modos sentí que una explicación con las referencias del doc sería mejor para alguien que busca una respuesta.
- Esta es una clase de utilidad con un montón de métodos estáticos para operar en la matriz dada
- asList es uno de esos métodos estáticos que toma una matriz de entrada y devuelve un objeto de java.util.Arrays.ArrayList que es una clase anidada estática que extiende AbstractList y que implementa la interfaz de lista.
- Así que Arrays.asList (inarray) devuelve una envoltura de lista alrededor de la matriz de entrada, pero esta envoltura es java.util.Arrays.ArrayList y no java.util.ArrayList y se refiere a la misma matriz por lo que agregar más elementos a la matriz empaquetada de lista afectaría orignal también y tampoco podemos cambiar la longitud.
ArrayList tiene muchos constructores sobrecargados
public ArrayList () - // devuelve el arraylist con la capacidad predeterminada 10
public ArrayList (Colección c)
public ArrayList (int initialCapacity)
Entonces, cuando pasemos 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 a la matriz orignal ) copia poco profunda de la matriz original ( copia poco profunda significa que solo copia sobre las referencias y no crea un nuevo conjunto de mismos objetos como en la matriz orignal)
Resumen de la diferencia -
cuando la lista se crea sin utilizar el nuevo operador Arrays.asList () método devuelve Wrapper lo que significa
1. puede realizar la operación agregar / actualizar.
2. Los cambios realizados en el conjunto original se reflejarán en la Lista también y viceversa.
Tenga en cuenta que, en Java 8, ''ia'' arriba debe ser Integer [] y no int []. Arrays.asList () de una matriz int devuelve una lista con un solo elemento. Al usar el fragmento de código de OP, el compilador detectará el problema, pero algunos métodos (por ej., Collections.shuffle ()) no harán lo que esperas.
Arrays.asList()
este método devuelve su propia implementación de List. Toma una matriz como argumento y construye métodos y atributos encima, ya que no está copiando ningún dato de una matriz, pero si usa la matriz original, esto causa una alteración en la matriz original cuando modifica lista devuelta por el método Arrays.asList()
.
por otra parte.
ArrayList(Arrays.asList());
es un constructor de la clase ArrayList
que toma una lista como argumento y devuelve una ArrayList
que es independiente de la lista, es decir. Arrays.asList()
en este caso pasó como un argumento. es por eso que ves estos resultados;
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
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
2.List<Integer> list2 = Arrays.asList(ia);
En la línea 2, Arrays.asList(ia)
devuelve una referencia de List
del objeto de clase interna definido en Arrays
, que también se llama ArrayList
pero es privado y solo se extiende AbstractList
. Esto significa que lo que regresó de Arrays.asList(ia)
es un objeto de clase diferente de lo que obtienes de new ArrayList<Integer>
.
No puede usar algunas operaciones en la línea 2 porque la clase privada interna dentro de 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 objeto ArrayList
copiando elementos de lo que obtienes de la línea 2. Así puedes hacer lo que quieras ya que java.util.ArrayList
proporciona todos esos métodos.
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
En este caso, list1
es de tipo ArrayList
.
List<Integer> list2 = Arrays.asList(ia);
Aquí, la lista se devuelve como una vista de List
, lo que significa que solo tiene los métodos asociados a esa interfaz. De ahí que algunos métodos no estén permitidos en list2
.
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
Aquí, estás creando una nueva 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:
ArrayList list1 = (ArrayList)Arrays.asList(ia);
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());
}
}
}