Eliminar elemento de una matriz en Java

En este tutorial, mostraremos ejemplos de cómo eliminar un elemento de una matriz en Java usando dos matrices, ArrayUtils.remove(), un bucle for y System.arraycopy().

Introducción

Este tutorial repasará algunas técnicas comunes para eliminar elementos de arreglos Java. La manipulación de elementos de matriz es una tarea extremadamente común, ya que se pueden encontrar discusiones al respecto en muchos foros, particularmente en StackOverflow.

Aquí hay una lista de las técnicas y métodos que repasaremos en este artículo:

Breve informe sobre matrices

Los arreglos son estructuras de datos comunes en muchos lenguajes de programación. Cada matriz se almacena en un solo bloque de memoria y permite el almacenamiento secuencial y la manipulación simple de elementos:

java array in memory

[Crédito: códigoparaganar]{.small}

Los elementos se almacenan secuencialmente uno tras otro. Cuando alguien quiere acceder a un elemento en un índice determinado, la aritmética de punteros (que es el mecanismo oculto) permite obtener de forma rápida y eficiente cualquier elemento en particular.

Si el índice de un elemento solicitado es 3, el mecanismo subyacente simplemente necesita tomar la dirección de memoria del cero-ésimo elemento y agregar tres veces el tamaño de cada elemento. Dado que todos los elementos de la matriz tienen el mismo tamaño, este tipo de cálculo conduce directamente al elemento con índice 3. Además, esto sucede en la complejidad O(1), lo que significa que es lo más rápido posible.

Lo que dificulta la eliminación de un elemento de matriz es el hecho de que todos los elementos se almacenan secuencialmente en un solo bloque de memoria. Debido a la naturaleza de la ubicación de la memoria de la matriz, es simplemente imposible eliminar el elemento directamente.

En cambio, para "eliminar" cualquier elemento, todos los elementos subsiguientes deben desplazarse hacia atrás un lugar. Esto creará la ilusión de que se eliminó un elemento específico.

Usando dos arreglos

La forma más simple de Java puro de hacer esto es crear una nueva matriz, un elemento más corto que el original y copiar todos los elementos, excepto el que nos gustaría eliminar, en él:

1
2
3
4
5
6
7
int[] copy = new int[array.length - 1];

for (int i = 0, j = 0; i < array.length; i++) {
    if (i != index) {
        copy[j++] = array[i];
    }
}

Aquí, simplemente estamos iterando sobre la matriz original y copiando elementos de la matriz original a la nueva matriz, omitiendo la que nos gustaría eliminar.

La matriz copiar ahora consta de:

1
10, 20, 30, 50, 60, 70, 80, 90, 100

ArrayUtils.remove()

En caso de que ya esté usando la biblioteca Apache Commons, puede usar el método ArrayUtils.remove().

Antes de trabajar con Apache Commons, querremos agregarlo a nuestro proyecto:

1
2
3
4
5
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>${version}</version>
</dependency>

Usar el método es realmente simple. Simplemente le proporcionamos la matriz de la que nos gustaría eliminar un elemento y su índice:

1
2
3
int[] array = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int index = 3;
array = ArrayUtils.remove(array, index);

Luego devuelve la nueva matriz, que se almacena en la variable array:

1
10, 20, 30, 50, 60, 70, 80, 90, 100

Usando un bucle for

La forma aparentemente más simple de eliminar un elemento es iterar la matriz manualmente usando un bucle for. Alternativamente, también se puede usar un bucle while pero for es mucho más adecuado para este tipo de tarea.

Digamos, queremos eliminar el tercer elemento:

1
2
int[] array = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int index = 3;

El elemento correspondiente al índice 3 es 40. Para eliminar este elemento, simplemente "cambiamos" todos los elementos después de él. Esto significa que vamos a iterar a través de todos los elementos después de 40 y simplemente "moverlos" un lugar a la izquierda.

Como no es posible simplemente mover un elemento, copiamos su valor en su lugar. Las copias posteriores sobrescribirán los valores originales y el resultado será como si toda la parte derecha de la matriz se desplazara hacia la izquierda en uno:

1
2
3
for (int i = index; i < array.length - 1; i++) {
    array[i] = array[i + 1];
}

Si fuéramos e imprimiéramos la matriz modificada, este sería el resultado:

1
10, 20, 30, 50, 60, 70, 80, 90, 100, 100

Las matrices son de longitud fija. El último elemento, 100, está duplicado debido a esto. Usando una sola matriz, es imposible eliminar un elemento sin llenar el nuevo espacio con algún valor.

Podría anularlo con un valor ficticio, como -1, pero esta solución no es muy válida. Esto se elimina con Usando dos arreglos.

System.arraycopy

Una forma abreviada de hacer exactamente lo mismo que antes pero en una sola línea de código es con el método System.arraycopy():

1
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

El método acepta una matriz de origen y la posición desde la cual para comenzar a copiar. También acepta una matriz de destino y la posición en la que empezar a copiar. El argumento final es el número de elementos a copiar de la matriz de origen.

El arraycopy generalmente se usa para copiar contenidos de una matriz de origen a una matriz de destino. Sin embargo, también podemos copiar una matriz, o una parte de ella, en sí misma. Esto nos permite desplazar una parte hacia la izquierda como la última vez:

1
2
int[] array = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int index = 3;

Para eliminar el elemento, solo necesitamos escribir esta línea de código:

1
System.arraycopy(array, index + 1, array, index, array.length - index - 1);

El método copiará todos los elementos de la matriz de origen (matriz) comenzando una posición a la derecha del índice. Los elementos se copiarán en la misma matriz (array) comenzando exactamente en index. El resultado será un desplazamiento percibido de todos los elementos a la derecha del elemento que queríamos eliminar.

Si imprimiéramos el resultado, aún veríamos que el elemento 100 se duplica por la misma razón que en la sección anterior.

Conclusión

En este tutorial, mostramos algunas formas de eliminar elementos de matriz. Algunos son rápidos y sucios, mientras que otros requieren una sobrecarga adicional, como el uso de bibliotecas adicionales. Siempre es mejor pensar en estas cosas de antemano para tener una idea de qué tipo de enfoque es el adecuado para una situación determinada.

La lista de técnicas que se muestran en este tutorial no es exhaustiva. Hay muchas maneras de ser creativo en la programación, por lo que estamos seguros de que puede encontrar otros enfoques interesantes para eliminar elementos de las matrices.