JavaRush /Blog Java /Random-ES /Las 10 preguntas principales sobre colecciones en Java
FedoraLinux
Nivel 21
Москва

Las 10 preguntas principales sobre colecciones en Java

Publicado en el grupo Random-ES
El artículo es una traducción del artículo " Las 10 preguntas principales sobre las colecciones de Java " . A continuación se muestran las preguntas más populares sobre colecciones en Java, formuladas y analizadas en Stackowerflow. Antes de abordar estas preguntas, sería bueno observar el diagrama de jerarquía de clases. 1. ¿Cuándo utilizar LinkedList en lugar de ArrayList? Una ArrayList es de hecho una matriz; se puede acceder a sus elementos directamente por índice. Si la matriz se desborda, será necesaria una nueva con más espacio. Colocar y mover todos los elementos llevará O(n) tiempo. Además, es necesario agregar y eliminar elementos para mover elementos existentes en la matriz. Este es quizás el mayor inconveniente de utilizar ArrayList. LinkedList es una lista doble de enlaces de elementos. Así, para acceder al elemento del centro, hay que buscar desde el principio hasta el final de la hoja. Por otro lado, agregar y eliminar un elemento en una LinkedList es más rápido porque estas operaciones solo cambian la lista misma. Los peores tiempos se comparan a continuación:
Método Lista de arreglo Lista enlazada
obtener (índice) O(1) En)
agregar(E) En) O(1)
agregar(E, índice) En) En)
eliminar (índice) En) En)
Iterador.remove() En) O(1)
Iterador.add(E) En) O(1)
A pesar del tiempo de ejecución, el uso de memoria debe considerarse individualmente para listas grandes. En una LinkedList, cada nodo debe tener al menos dos punteros adicionales para vincular los nodos anterior y siguiente, mientras que en una ArrayList, solo se necesita una matriz de elementos. Más comparaciones de listas ArrayList, LinkedList y Vector . 2. Equivalente eficiente para eliminar elementos durante la iteración de la colección. La única forma correcta de modificar (eliminar elementos) una colección durante la iteración es usar Iterator.remove() . Por ejemplo: El error más común es: Obtendrá una excepción ConcurrentModificationException al ejecutar el código anterior. Esto sucede porque el iterador se generó para moverse por toda la lista, pero al mismo tiempo se cambia la hoja llamando a Iterator.remove(). Como está escrito en la documentación para esta excepción, Iterator itr = list.iterator(); while(itr.hasNext()) { // do something itr.remove(); } for(Integer i: list) { list.remove(i); }
"Por lo general, no está permitido que un hilo modifique una colección mientras otro hilo está iterando sobre ella".
En general, es inaceptable que un hilo modifique una colección mientras otro hilo la atraviesa. 3. ¿Cómo convertir Lista a matriz int[]? La forma más sencilla de hacerlo es utilizar ArrayUtils , ubicado en la biblioteca Apache Commons Lang . int[] array = ArrayUtils.toPrimitive(list.toArray(new Integer[0])); No hay ningún atajo para esta expresión en el JDK. Recuerde que no puede usar List.toArray() porque esta expresión convierte List en Integer[] (que no es un tipo primitivo). La forma correcta sería la siguiente opción: int[] array = new int[list.size()]; for(int i=0; i < list.size(); i++) { array[i] = list.get(i); } 4. ¿Cómo convertir una matriz int[] en una Lista? La forma más sencilla también es utilizar ArrayUtils en la biblioteca Apache Commons Lang , como se indica arriba. List list = Arrays.asList(ArrayUtils.toObject(array)); Además, no existe ningún atajo para esta expresión en el JDK. 5. ¿Cuál es la mejor forma de filtrar la colección? Puede utilizar paquetes de terceros como Guava o Apache Commons Lang para aumentar la funcionalidad. Ambos paquetes tienen un método filter() (en la clase Collections2 de Guava y CollectionUtils de Apache). El método filter() devolverá elementos que coincidan con el predicado dado. En JDK todo es más complicado. La buena noticia es que se agregarán predicados en Java 8 , pero por ahora necesitas usar Iterator para recorrer toda la colección. Por supuesto, puedes imitar el camino seguido por Guava y Apache familiarizándote con la nueva interfaz Predicate. Ahora podemos usar el siguiente código para filtrar la colección: 6. ¿Cómo convertir fácilmente Lista en Conjunto? Hay dos formas de hacer esto, dependiendo de cómo desee definir la igualdad. El primer fragmento de código coloca la lista en un HashSet. El duplicado en este caso está determinado principalmente por hashCode(). Normalmente esto funcionará. Pero si necesita tener en cuenta la ruta de comparación, sería mejor utilizar la segunda parte del código, donde puede definir su propio comparador. 7. ¿Cómo puedo eliminar elementos duplicados de un ArrayList? Esta pregunta está algo relacionada con la pregunta anterior. Si el orden de los elementos en ArrayList no le importa, una decisión inteligente sería colocar la hoja en un Conjunto para eliminar duplicados y luego devolverla a la Lista. A continuación se muestra un ejemplo. Si el orden de los elementos es importante para usted, entonces puede garantizar el orden colocando la lista en un LinkedHashSet , que se encuentra en el JDK estándar. 8. Colección ordenada int[] array = {1,2,3,4,5}; List list = new ArrayList (); for(int i: array) { list.add(i); } Iterator itr = list.iterator(); while(itr.hasNext()) { int i = itr.next(); if (i > 5) { // filter all ints bigger than 5 itr.remove(); } } public interface Predicate { boolean test(T o); } public static void filter(Collection collection, Predicate predicate) { if ((collection != null) && (predicate != null)) { Iterator itr = collection.iterator(); while(itr.hasNext()) { T obj = itr.next(); if (!predicate.test(obj)) { itr.remove(); } } } } filter(list, new Predicate () { public boolean test(Integer i) { return i <= 5; } }); Set set = new HashSet (list); Set set = new TreeSet (aComparator); set.addAll(list); ArrayList** list = ... // initial a list with duplicate elements Set set = new HashSet (list); list.clear(); list.addAll(set); Hay varias formas de admitir una colección ordenada en Java. Todos ellos proporcionan una colección en orden natural o mediante un comparador específico. En el caso del orden natural, también es necesario implementar la interfaz Comparable en el elemento.
  1. Collections.sort() puede ordenar una Lista. Como se indica en la documentación de Java, este tipo es estable y garantiza un rendimiento n log(n).
  2. PriorityQueue proporciona una cola ordenada. La diferencia entre PriorityQueue y Collections.sort() es que PriorityQueue mantiene el orden de la cola todo el tiempo, pero solo puede obtener el primer elemento de la cola. No puedes acceder aleatoriamente a un elemento como PriorityQueue.get(4).
  3. Si no hay duplicados en la colección, puede seleccionar TreeSet . Al igual que PriorityQueue, TreeSet mantiene un conjunto ordenado en todo momento. Puede obtener el elemento más pequeño o más grande de un TreeSet, pero aún así no puede tener acceso aleatorio a los elementos.
En pocas palabras, Collections.sort() proporciona una lista ordenada de una sola vez. PriorityQueue y TreeSet mantienen una colección ordenada en todo momento, a costa de la falta de acceso indexado a los elementos. 9. Collections.emptyList() o nueva instancia. La misma pregunta se aplica a vacíoMap() y vacíoSet(). Ambos métodos devuelven una lista vacía, pero Collections.emptyList() es una lista inmutable. Esto significa que no puede agregar nuevos elementos a una lista "vacía". En segundo plano, cada llamada al método Collections.emptyList() en realidad no crea una nueva instancia de la lista vacía. En su lugar, reutilizará la instancia vacía ya existente. Si está familiarizado con Singleton como patrón de diseño , debe comprender lo que significa. Esto debería brindarle un mejor rendimiento si lo llama con frecuencia. 10 Copiar una colección, Collections.copy() Hay dos formas de copiar una lista de origen a una lista de destino. Una forma es utilizar el constructor ArrayList. Otra forma es utilizar el método Collections.copy() . Aviso en la primera línea: estamos asignando una lista que tiene al menos la misma longitud que la lista original, porque la documentación de Java sobre colecciones dice: ArrayList dstList = new ArrayList (srcList);
La lista de destino debe ser al menos tan larga como la lista de origen.
Lo que significa que la lista final no debe ser más corta que la original. Ambos métodos son copias superficiales. Entonces, ¿cuál es la diferencia entre estos dos métodos? Primero, Collections.copy() no reasignará la capacidad de la colección dstList, incluso si dstList no tiene suficiente espacio para contener todos los elementos de srcList. En su lugar, arrojará IndexOutOfBoundsException . Uno podría preguntarse si esto tiene algún beneficio. La razón es que esto garantiza que el método se ejecute linealmente en el tiempo. Esto también es adecuado cuando desea reutilizar matrices en lugar de reasignar memoria en el constructor ArrayList. En lugar de una conclusión. Si después de leer el artículo todavía tienes preguntas, no dudes en plantearlas en los comentarios. Además, si encuentras alguna inexactitud en la traducción o cualquier otro error, entonces escribe al PM, se corregirá y se te agradecerá. Original. ArrayList dstList = new ArrayList (srcList.size()); Collections.copy(dstList, srcList);
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION