Categorías
Basics Classes & Interfaces Collections Top 10

Las 10 preguntas principales sobre las colecciones de Java

Las siguientes son las preguntas más populares de las colecciones de Java formuladas y discutidas en Stackoverflow. Antes de mirar esas preguntas, es una buena idea ver el diagrama de jerarquía de clases.

1. ¿Cuándo usar LinkedList sobre ArrayList?

Lista de arreglo es esencialmente una matriz. Se puede acceder a sus elementos directamente por índice. Pero si la matriz está llena, se necesita una nueva matriz más grande para asignar y mover todos los elementos a la nueva matriz tomará En) hora. Además, agregar o eliminar un elemento necesita mover elementos existentes en una matriz. Esta podría ser la mayor desventaja para usar ArrayList.

Lista enlazada es una lista de doble enlace. Por tanto, para acceder a un elemento en el medio, tiene que buscar desde el principio de la lista. Por otro lado, agregar y eliminar un elemento en LinkedList es más rápido, porque solo cambia la lista localmente.

En resumen, el peor caso de comparación de la complejidad del tiempo es el siguiente:

                   | Arraylist | LinkedList
 ------------------------------------------
 get(index)        |    O(1)   |   O(n)
 add(E)            |    O(n)   |   O(1)
 add(E, index)     |    O(n)   |   O(n)
 remove(index)     |    O(n)   |   O(n)
 Iterator.remove() |    O(n)   |   O(1)
 Iterator.add(E)   |    O(n)   |   O(1)

A pesar del tiempo de ejecución, el uso de la memoria también debe considerarse especialmente para listas grandes. En Lista enlazada, cada nodo necesita al menos dos punteros adicionales para vincular los nodos anterior y siguiente; mientras en Lista de arreglo, solo se necesita una serie de elementos.

Más comparaciones entre lista.

2. Equivalente eficiente para eliminar elementos mientras se itera la colección

La única forma correcta de modificar una colección mientras se itera es usando Iterador.retirar(). Por ejemplo,

Iterator<Integer> itr = list.iterator();
while(itr.hasNext()) {
   // do something
   itr.remove();
}

Uno mas frecuente incorrecto el código es

for(Integer i: list) {
  list.remove(i);
}

Obtendrás un ConcurrentModificationException ejecutando el código anterior. Esto se debe a que se ha generado un iterador (en por declaración) para recorrer la lista, pero al mismo tiempo la lista es cambiada por Iterador.retirar(). En Java, «generalmente no está permitido que un subproceso modifique una colección mientras otro subproceso está iterando sobre ella».

3. Cómo convertir List a int[]?

La forma más fácil podría ser usar ArrayUtils en Apache Commons Lang Biblioteca.

int[] array = ArrayUtils.toPrimitive(list.toArray(new Integer[0]));
  Implementar comparable para un TreeSet

En JDK, no hay atajos. Tenga en cuenta que no puede usar Lista.toArray (), porque eso convertirá Lista a Entero[]. El camino correcto es seguir,

int[] array = new int[list.size()];
for(int i=0; i < list.size(); i++) {
  array[i] = list.get(i);
}

4. Cómo convertir int[] en la lista?

La forma más fácil podría todavía estar usando ArrayUtils en Apache Commons Lang biblioteca, como a continuación.

List list = Arrays.asList(ArrayUtils.toObject(array));

En JDK, tampoco hay atajos.

int[] array = {1,2,3,4,5};
List<Integer> list = new ArrayList<Integer>();
for(int i: array) {
  list.add(i);
}

5. ¿Cuál es la mejor forma de filtrar una colección?

Nuevamente, puede usar un paquete de terceros, como Guayaba o Apache Commons Lang para cumplir con esta función. Ambos proporcionan un filtrar() método (en Colecciones2 de Guayaba y en ColecciónUtils de Apache). La filtrar() El método devolverá elementos que coincidan con un determinado Predicado.

En JDK, las cosas se vuelven más difíciles. Una buena noticia es que en Java 8, Predicado será añadido. Pero por ahora tienes que usar Iterador para recorrer toda la colección.

Iterator<Integer> itr = list.iterator();
while(itr.hasNext()) {
   int i = itr.next();
   if (i > 5) { // filter all ints bigger than 5
      itr.remove();
   }
}

Por supuesto, puede imitar la forma de lo que hicieron Guava y Apache, introduciendo una nueva interfaz Predicado. Eso también podría ser lo que harán los desarrolladores más avanzados.

public interface Predicate<T> {
   boolean test(T o);
}
 
public static <T> void filter(Collection<T> collection, Predicate<T> predicate) {
    if ((collection != null) && (predicate != null)) {
       Iterator<T> itr = collection.iterator();
          while(itr.hasNext()) {
            T obj = itr.next();
            if (!predicate.test(obj)) {
               itr.remove();
            }
        }
    }
}

Entonces podemos usar el siguiente código para filtrar una colección:

  ¿Constructores de sub y súper clases en Java?
filter(list, new Predicate<Integer>() {
    public boolean test(Integer i) { 
       return i <= 5; 
    }
});

6. ¿La forma más sencilla de convertir una lista en un conjunto?

Hay dos formas de hacerlo, dependiendo de cómo desee igual definido. El primer fragmento de código pone una lista en un HashSet. Entonces, la duplicación se identifica principalmente por código hash(). En la mayoría de los casos, funcionará. Pero si necesita especificar la forma de comparación, es mejor usar la segunda parte del código donde puede definir su propio comparador.

Set<Integer> set = new HashSet<Integer>(list);
Set<Integer> set = new TreeSet<Integer>(aComparator);
set.addAll(list);

7. ¿Cómo elimino elementos repetidos de ArrayList?

Esta pregunta está bastante relacionada con la anterior.
Si no le importa el orden de los elementos en el Lista de arreglo, una forma inteligente es poner la lista en un conjunto para eliminar la duplicación y luego volver a moverla a la lista. Aqui esta el codigo

ArrayList** list = ... // initial a list with duplicate elements
Set<Integer> set = new HashSet<Integer>(list);
list.clear();
list.addAll(set);

Si le importa el orden, el orden se puede conservar poniendo una lista en un LinkedHashSet que está en el JDK estándar.

8. Colección ordenada

Hay un par de formas de mantener una colección ordenada en Java. Todos ellos proporcionan una colección en orden natural o por el comparador especificado. Por orden natural, también necesita implementar el Comparable interfaz en los elementos.

  1. Colecciones.clasificar() puede ordenar un Lista. Como se especifica en el javadoc, este tipo es establey garantía n log (n) actuación.
  2. PriorityQueue proporciona una cola ordenada. La diferencia entre PriorityQueue y Colecciones.clasificar() es eso, PriorityQueue mantener una cola de pedidos en todo momento, pero solo puede obtener el elemento principal de la cola. No puede acceder aleatoriamente a su elemento como PriorityQueue.obtener (4).
  3. Si no hay duplicación en la colección, TreeSet es otra opción. Igual que PriorityQueue, mantiene el conjunto ordenado en todo momento. Puedes conseguir el más bajo y mas alto elementos de la TreeSet. Pero aún no puede acceder aleatoriamente a su elemento.
  ¿Qué es exactamente nulo en Java?

En un short, Colecciones.clasificar() proporciona una lista ordenada de una sola vez. PriorityQueue y TreeSet mantener colecciones ordenadas en todo momento, a costa de no tener acceso indexado a los elementos.

9. Colecciones.lista vacía() vs nueva instancia

La misma pregunta se aplica a emptyMap () y conjunto vacio().

Ambos métodos devuelven una lista vacía, pero Colecciones.lista vacía() devuelve una lista que es inmutable. Esto significa que no puede agregar nuevos elementos al «vacío«lista. En el fondo, cada llamada de Colecciones.lista vacía() en realidad, no creará una nueva instancia de una lista vacía. En su lugar, reutilizará la instancia vacía existente. Si estas familiarizado único en el patrón de diseño, debes saber a qué me refiero. Así que esto le dará un mejor rendimiento si lo llama con frecuencia.

10 Colecciones. Copiar

Hay dos formas de copiar una lista de origen en una lista de destino. Una forma es usar Lista de arreglo constructor

ArrayList<Integer> dstList = new ArrayList<Integer>(srcList);

El otro es usar Colecciones.Copiar() (como a continuación). Tenga en cuenta la primera línea, asignamos una lista al menos tan larga como la lista de origen, porque en el javadoc de Colecciones, dice La lista de destinos debe ser al menos tan larga como la lista de origen.

ArrayList<Integer> dstList = new ArrayList<Integer>(srcList.size());
Collections.copy(dstList, srcList);

Ambos métodos son poco profundo Copiar. Entonces, cual es el diferencia entre estos dos métodos?

  • Primero, Colecciones.Copiar() no reasignará la capacidad de dstList incluso si dstList no tiene suficiente espacio para contener todo srcList elementos. En cambio, lanzará un IndexOutOfBoundsException. Uno puede preguntarse si tiene algún beneficio. Una razón es que garantiza que el método se ejecute en tiempo lineal. También es adecuado cuando desea reutilizar matrices en lugar de asignar nueva memoria en el constructor de Lista de arreglo.

  • Colecciones.Copiar() solo puedo aceptar Lista como origen y destino, mientras que Lista de arreglo acepta Colección como parámetro, por lo tanto más general.

Por Programación.Click

Más de 20 años programando en diferentes lenguajes de programación. Apasionado del code clean y el terminar lo que se empieza. ¿Programamos de verdad?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *