Buscar..


Introducción

Una lista es una colección ordenada de valores. En Java, las listas son parte de Java Collections Framework . Las listas implementan la interfaz java.util.List , que extiende java.util.Collection .

Sintaxis

  • ls.add (elemento E); // Agrega un elemento
  • ls.remove (elemento E); // Elimina un elemento
  • para (elemento E: ls) {} // itera sobre cada elemento
  • ls.toArray (nueva cadena [ls.length]); // Convierte una lista de cadenas a una matriz de cadenas
  • ls.get (índice int); // Devuelve el elemento en el índice especificado.
  • ls.set (índice int, elemento E); // Reemplaza el elemento en una posición especificada.
  • ls.isEmpty (); // Devuelve verdadero si la matriz no contiene elementos, de lo contrario, devuelve falso.
  • ls.indexOf (Objeto o); // Devuelve el índice de la primera ubicación del elemento especificado o, o, si no está presente, devuelve -1.
  • ls.lastIndexOf (Objeto o); // Devuelve el índice de la última ubicación del elemento especificado o, o, si no está presente, devuelve -1.
  • ls.size (); // Devuelve el número de elementos en la Lista.

Observaciones

Una lista es un objeto que almacena una colección ordenada de valores. "Ordenado" significa que los valores se almacenan en un orden particular: un elemento aparece primero, otro ocupa el segundo lugar, etc. Los valores individuales son comúnmente llamados "elementos". Las listas de Java suelen proporcionar estas características:

  • Las listas pueden contener cero o más elementos.
  • Las listas pueden contener valores duplicados. En otras palabras, un elemento se puede insertar en una lista más de una vez.
  • Las listas almacenan sus elementos en un orden particular, lo que significa que un elemento viene primero, uno viene a continuación, y así sucesivamente.
  • Cada elemento tiene un índice que indica su posición dentro de la lista. El primer elemento tiene índice 0, el siguiente tiene índice 1 y así sucesivamente.
  • Las listas permiten la inserción de elementos al principio, al final o en cualquier índice dentro de la lista.
  • Comprobar si una lista contiene un valor particular generalmente significa examinar cada elemento de la lista. Esto significa que el tiempo para realizar esta comprobación es O (n) , proporcional al tamaño de la lista.

Agregar un valor a una lista en algún punto que no sea el final moverá todos los siguientes elementos "hacia abajo" o "hacia la derecha". En otras palabras, agregar un elemento en el índice n mueve el elemento que solía estar en el índice n al índice n + 1 , y así sucesivamente. Por ejemplo:

List<String> list = new ArrayList<>();
list.add("world");
System.out.println(list.indexOf("world"));      // Prints "0"
// Inserting a new value at index 0 moves "world" to index 1
list.add(0, "Hello");
System.out.println(list.indexOf("world"));      // Prints "1"
System.out.println(list.indexOf("Hello"));      // Prints "0"

Ordenar una lista genérica

La clase Collections ofrece dos métodos estáticos estándar para ordenar una lista:

  • sort(List<T> list) aplicable a listas donde T extends Comparable<? super T> , y
  • sort(List<T> list, Comparator<? super T> c) aplicable a listas de cualquier tipo.

Aplicar lo anterior requiere modificar la clase de elementos de lista que se están ordenando, lo que no siempre es posible. También puede ser indeseable ya que, si bien proporciona la clasificación predeterminada, es posible que se requieran otras órdenes de clasificación en diferentes circunstancias, o la clasificación es una tarea única.

Considere que tenemos la tarea de ordenar los objetos que son instancias de la siguiente clase:

public class User {
    public final Long id;
    public final String username;

    public User(Long id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public String toString() {
        return String.format("%s:%d", username, id);
    }
}

Para utilizar Collections.sort(List<User> list) necesitamos modificar la clase de User para implementar la interfaz Comparable . Por ejemplo

public class User implements Comparable<User> {
    public final Long id;
    public final String username;

    public User(Long id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public String toString() {
        return String.format("%s:%d", username, id);
    }

    @Override
    /** The natural ordering for 'User' objects is by the 'id' field. */
    public int compareTo(User o) {
        return id.compareTo(o.id);
    }
}

(Aparte: muchas clases Java estándar como String , Long , Integer implementan la interfaz Comparable . Esto hace que las listas de esos elementos se puedan ordenar de forma predeterminada y simplifica la implementación de compare o compareTo en otras clases).

Con la modificación anterior, podemos ordenar fácilmente una lista de objetos de User según el orden natural de las clases. (En este caso, hemos definido que se ordenen según los valores de id ). Por ejemplo:

List<User> users = Lists.newArrayList(
    new User(33L, "A"),
    new User(25L, "B"),
    new User(28L, ""));
Collections.sort(users);

System.out.print(users);
// [B:25, C:28, A:33]

Sin embargo, supongamos que queremos ordenar los objetos de User por name lugar de por id . Alternativamente, supongamos que no pudimos cambiar la clase para que sea implementable como Comparable .

Aquí es donde el método de sort con el argumento del Comparator es útil:

Collections.sort(users, new Comparator<User>() {
    @Override
    /* Order two 'User' objects based on their names. */
    public int compare(User left, User right) {
        return left.username.compareTo(right.username);
    }
});
System.out.print(users);
// [A:33, B:25, C:28]
Java SE 8

En Java 8 puedes usar un lambda en lugar de una clase anónima. Este último se reduce a una sola línea:

Collections.sort(users, (l, r) -> l.username.compareTo(r.username));

Además, Java 8 agrega un método de sort predeterminado en la interfaz de List , lo que simplifica la clasificación aún más.

users.sort((l, r) -> l.username.compareTo(r.username))

Creando una lista

Dando a tu lista un tipo

Para crear una lista necesita un tipo (cualquier clase, por ejemplo, String ). Este es el tipo de su List . La List solo almacenará objetos del tipo especificado. Por ejemplo:

List<String> strings;

Puede almacenar "string1" , "hello world!" , "goodbye" , etc., pero no puede almacenar 9.2 , sin embargo:

List<Double> doubles;

Puede almacenar 9.2 , pero no "hello world!" .

Inicializando tu lista

Si intentas agregar algo a las listas anteriores, obtendrás una NullPointerException, ¡porque las strings y los doubles nulos iguales!

Hay dos formas de inicializar una lista:

Opción 1: usar una clase que implemente lista

List es una interfaz, lo que significa que no tiene un constructor, sino métodos que una clase debe reemplazar. ArrayList es el más comúnmente utilizado List , aunque LinkedList también es común. Así que inicializamos nuestra lista de esta manera:

List<String> strings = new ArrayList<String>();

o

List<String> strings = new LinkedList<String>();
Java SE 7

A partir de Java SE 7, puede utilizar un operador de diamante :

List<String> strings = new ArrayList<>();

o

List<String> strings = new LinkedList<>();

Opción 2: usar la clase Colecciones

La clase Collections proporciona dos métodos útiles para crear listas sin una variable de List :

  • emptyList() : devuelve una lista vacía.
  • singletonList(T) : crea una lista de tipo T y agrega el elemento especificado.

Y un método que utiliza una List existente para completar los datos:

  • addAll(L, T...) : agrega todos los elementos especificados a la lista pasada como primer parámetro.

Ejemplos:

import java.util.List;
import java.util.Collections;

List<Integer> l = Collections.emptyList();
List<Integer> l1 = Collections.singletonList(42);
Collections.addAll(l1, 1, 2, 3);

Operaciones de acceso posicional

La API de lista tiene ocho métodos para las operaciones de acceso posicional:

  • add(T type)
  • add(int index, T type)
  • remove(Object o)
  • remove(int index)
  • get(int index)
  • set(int index, E element)
  • int indexOf(Object o)
  • int lastIndexOf(Object o)

Entonces, si tenemos una lista:

List<String> strings = new ArrayList<String>();

Y queríamos añadir las cuerdas "¡Hola mundo!" y "adiós mundo!" Para ello, lo haríamos como tal:

strings.add("Hello world!");
strings.add("Goodbye world!");

Y nuestra lista contendría los dos elementos. Ahora digamos que queríamos agregar "¡Programa empezando!" al frente de la lista. Haríamos esto así:

strings.add(0, "Program starting!");

NOTA: El primer elemento es 0.

Ahora, si quisiéramos eliminar el "¡Adiós mundo!" Línea, podríamos hacerlo así:

strings.remove("Goodbye world!");

Y si quisiéramos eliminar la primera línea (que en este caso sería "¡Programa empezando!", Podríamos hacerlo así:

strings.remove(0);

Nota:

  1. Agregar y eliminar elementos de la lista modifica la lista, y esto puede llevar a una ConcurrentModificationException si la lista se está iterando simultáneamente.

  2. La adición y eliminación de elementos puede ser O(1) u O(N) según la clase de lista, el método utilizado y si está agregando / eliminando un elemento al inicio, al final o en medio de la lista.

Para recuperar un elemento de la lista en una posición específica, puede utilizar el E get(int index); Método de la lista API. Por ejemplo:

strings.get(0);

Volverá el primer elemento de la lista.

Puede reemplazar cualquier elemento en una posición específica usando el set(int index, E element); . Por ejemplo:

strings.set(0,"This is a replacement");

Esto establecerá la Cadena "Esto es un reemplazo" como el primer elemento de la lista.

Nota: El método de configuración sobrescribirá el elemento en la posición 0. No agregará la nueva Cadena en la posición 0 y empujará la antigua a la posición 1.

El int indexOf(Object o); devuelve la posición de la primera aparición del objeto pasado como argumento. Si no hay apariciones del objeto en la lista, se devuelve el valor -1. Continuando con el ejemplo anterior si llama:

strings.indexOf("This is a replacement")

se espera que se devuelva el 0 cuando configuramos la Cadena "Esto es un reemplazo" en la posición 0 de nuestra lista. En caso de que haya más de una aparición en la lista cuando int indexOf(Object o); Se llama entonces como se mencionó se devolverá el índice de la primera aparición. Al llamar a int lastIndexOf(Object o) , puede recuperar el índice de la última aparición en la lista. Así que si agregamos otro "Este es un reemplazo":

strings.add("This is a replacement");
strings.lastIndexOf("This is a replacement");

Esta vez se devolverá el 1 y no el 0;

Iterando sobre elementos en una lista

Para el ejemplo, digamos que tenemos una Lista de tipo String que contiene cuatro elementos: "hola", "cómo", "son", "usted?"

La mejor manera de iterar sobre cada elemento es usando un bucle para cada uno:

public void printEachElement(List<String> list){
    for(String s : list){
        System.out.println(s);
    }
}

Que imprimiría:

hello,
how
are
you?

Para imprimirlos todos en la misma línea, puede usar un StringBuilder:

public void printAsLine(List<String> list){
    StringBuilder builder = new StringBuilder();
    for(String s : list){
        builder.append(s);
    }
    System.out.println(builder.toString());
}

Se imprimirá:

hello, how are you?

Alternativamente, puede usar la indexación de elementos (como se describe en Acceso a un elemento en el índice de ArrayList ) para iterar una lista. Advertencia: este enfoque es ineficiente para las listas enlazadas.

Eliminar elementos de la lista B que están presentes en la lista A

Supongamos que tiene 2 listas A y B, y desea eliminar de B todos los elementos que tiene en A, el método en este caso es

 List.removeAll(Collection c);

#Ejemplo:

public static void main(String[] args) {
    List<Integer> numbersA = new ArrayList<>();
    List<Integer> numbersB = new ArrayList<>();
    numbersA.addAll(Arrays.asList(new Integer[] { 1, 3, 4, 7, 5, 2 }));
    numbersB.addAll(Arrays.asList(new Integer[] { 13, 32, 533, 3, 4, 2 }));
    System.out.println("A: " + numbersA);
    System.out.println("B: " + numbersB);

    numbersB.removeAll(numbersA);
    System.out.println("B cleared: " + numbersB);
    }

esto imprimirá

A: [1, 3, 4, 7, 5, 2]

B: [13, 32, 533, 3, 4, 2]

B despejado: [13, 32, 533]

Encontrando elementos comunes entre 2 listas.

Supongamos que tiene dos listas: A y B, y necesita encontrar los elementos que existen en ambas listas.

Puede hacerlo simplemente invocando el método List.retainAll() .

Ejemplo:

public static void main(String[] args) {
    List<Integer> numbersA = new ArrayList<>();
    List<Integer> numbersB = new ArrayList<>();
    numbersA.addAll(Arrays.asList(new Integer[] { 1, 3, 4, 7, 5, 2 }));
    numbersB.addAll(Arrays.asList(new Integer[] { 13, 32, 533, 3, 4, 2 }));

    System.out.println("A: " + numbersA);
    System.out.println("B: " + numbersB);
    List<Integer> numbersC = new ArrayList<>();
    numbersC.addAll(numbersA);
    numbersC.retainAll(numbersB);

    System.out.println("List A : " + numbersA);
    System.out.println("List B : " + numbersB);
    System.out.println("Common elements between A and B: " + numbersC);

}

Convertir una lista de enteros en una lista de cadenas

List<Integer> nums = Arrays.asList(1, 2, 3);
List<String> strings = nums.stream()
    .map(Object::toString)
    .collect(Collectors.toList());

Es decir:

  1. Crear un flujo de la lista
  2. Mapea cada elemento usando Object::toString
  3. Recopile los valores de String en una List usando Collectors.toList()

Creación, adición y eliminación de elementos de un ArrayList

ArrayList es una de las estructuras de datos incorporadas en Java. Es una matriz dinámica (donde el tamaño de la estructura de datos no necesita declararse primero) para almacenar elementos (Objetos).

Extiende la clase AbstractList e implementa la interfaz de List . Un ArrayList puede contener elementos duplicados donde mantiene el orden de inserción. Se debe tener en cuenta que la clase ArrayList no está sincronizada, por lo que se debe tener cuidado al manejar la concurrencia con ArrayList . ArrayList permite el acceso aleatorio porque la matriz funciona en la base del índice. La manipulación es lenta en ArrayList debido a los cambios que ocurren a menudo cuando se elimina un elemento de la lista de arreglos.

Un ArrayList se puede crear de la siguiente manera:

List<T> myArrayList = new ArrayList<>();

Donde T ( Genéricos ) es el tipo que se almacenará dentro de ArrayList .

El tipo de ArrayList puede ser cualquier Objeto. El tipo no puede ser un tipo primitivo (en su lugar, use sus clases de envoltorio ).

Para agregar un elemento al ArrayList , use el método add() :

myArrayList.add(element);

O para agregar un artículo a un determinado índice:

myArrayList.add(index, element); //index of the element should be an int (starting from 0)

Para eliminar un elemento de ArrayList , use el método remove() :

myArrayList.remove(element);

O bien, para eliminar un elemento de un determinado índice:

myArrayList.remove(index); //index of the element should be an int (starting from 0)

Sustitución in situ de un elemento de lista

Este ejemplo se trata de reemplazar un elemento de la List mientras se asegura que el elemento de reemplazo esté en la misma posición que el elemento que se reemplaza.

Esto se puede hacer usando estos métodos:

  • conjunto (índice int, tipo T)
  • int indexOf (tipo T)

Considere una ArrayList contenga los elementos "¡Programa empezando!", "¡Hola mundo!" y "adiós mundo!"

List<String> strings = new ArrayList<String>();
strings.add("Program starting!");
strings.add("Hello world!");
strings.add("Goodbye world!");

Si conocemos el índice del elemento que queremos reemplazar, simplemente podemos usar set siguiente manera:

strings.set(1, "Hi world");

Si no conocemos el índice, podemos buscarlo primero. Por ejemplo:

int pos = strings.indexOf("Goodbye world!");
if (pos >= 0) {
    strings.set(pos, "Goodbye cruel world!");
}

Notas:

  1. La operación set no generará una ConcurrentModificationException .
  2. La operación set es rápida ( O(1) ) para ArrayList pero lenta ( O(N) ) para una lista LinkedList .
  3. Una búsqueda indexOf en un ArrayList o LinkedList es lenta ( O(N) ).

Haciendo una lista no modificable

La clase Colecciones proporciona una manera de hacer que una lista no sea modificable:

List<String> ls = new ArrayList<String>();
List<String> unmodifiableList = Collections.unmodifiableList(ls);

Si desea una lista no modificable con un elemento, puede utilizar:

List<String> unmodifiableList = Collections.singletonList("Only string in the list");

Mover objetos alrededor de la lista

La clase Colecciones le permite mover objetos en la lista usando varios métodos (ls es la Lista):

Invertir una lista:

Collections.reverse(ls);

Posiciones rotativas de elementos en una lista.

El método de rotación requiere un argumento entero. Este es el número de puntos para moverlo a lo largo de la línea. Un ejemplo de esto es a continuación:

List<String> ls = new ArrayList<String>();
ls.add(" how");
ls.add(" are");
ls.add(" you?");
ls.add("hello,");
Collections.rotate(ls, 1);

for(String line : ls) System.out.print(line);
System.out.println();

Esto imprimirá "hola, ¿cómo estás?"

Mezclando elementos alrededor de una lista

Usando la misma lista anterior, podemos barajar los elementos en una lista:

Collections.shuffle(ls);

También podemos darle un objeto java.util.Random que utiliza para colocar objetos aleatoriamente en puntos:

Random random = new Random(12); 
Collections.shuffle(ls, random);

Clases implementando Lista - Pros y Contras

La interfaz de List está implementada por diferentes clases. Cada uno de ellos tiene su propio camino para implementarlo con diferentes estrategias y proporcionar diferentes pros y contras.


Clases implementando la lista

Estas son todas las clases public en Java SE 8 que implementan la interfaz java.util.List :

  1. Clases abstractas:
    • Lista abstracta
    • AbstractSequentialList
  2. Clases de concreto:
    • Lista de arreglo
    • Lista de atributos
    • CopyOnWriteArrayList
    • Lista enlazada
    • Lista de roles
    • RoleUnresolvedList
    • Apilar
    • Vector

Pros y contras de cada implementación en términos de complejidad de tiempo

Lista de arreglo

public class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable

ArrayList es una implementación de matriz de tamaño variable de la interfaz de lista. Al almacenar la lista en una matriz, ArrayList proporciona métodos (además de los métodos que implementan la interfaz de la Lista ) para manipular el tamaño de la matriz.

Inicializar ArrayList de entero con tamaño 100

List<Integer> myList = new ArrayList<Integer>(100); // Constructs an empty list with the specified initial capacity.

- PROS:

Las operaciones size, isEmpty, get , set , iterator y listIterator se ejecutan en tiempo constante. Por lo tanto, obtener y configurar cada elemento de la Lista tiene el mismo costo de tiempo :

int e1 = myList.get(0);  //   \
int e2 = myList.get(10); //    | => All the same constant cost => O(1)
myList.set(2,10);        //   /

- CONTRAS:

La implementación con una matriz (estructura estática) que agrega elementos sobre el tamaño de la matriz tiene un gran costo debido al hecho de que es necesario realizar una nueva asignación para toda la matriz. Sin embargo, a partir de la documentación :

La operación de adición se ejecuta en tiempo constante amortizado, es decir, agregar n elementos requiere tiempo O (n)

La eliminación de un elemento requiere O (n) tiempo.


Lista de atributos

En venir


CopyOnWriteArrayList

En venir


Lista enlazada

public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable

LinkedList se implementa mediante una lista doblemente enlazada, una estructura de datos vinculados que consiste en un conjunto de registros vinculados secuencialmente llamados nodos.

Iitialize LinkedList of Integer

List<Integer> myList = new LinkedList<Integer>(); // Constructs an empty list.

- PROS:

Agregar o eliminar un elemento al principio de la lista o al final tiene un tiempo constante.

myList.add(10);  // \
myList.add(0,2); //  | => constant time => O(1)
myList.remove(); // /

- CONTRA: De la documentación :

Las operaciones que indizan en la lista recorrerán la lista desde el principio o el final, lo que esté más cerca del índice especificado.

Operaciones como:

myList.get(10);    // \
myList.add(11,25); //  | => worst case done in O(n/2)
myList.set(15,35); // /

Lista de roles

En venir


RoleUnresolvedList

En venir


Apilar

En venir


Vector

En venir




Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow