2009-03-13 65 views
113

¿Hay alguna manera rápida (y bonita) de eliminar un elemento de una matriz en Java?Eliminar un elemento de una matriz (Java)

+2

Aunque la pregunta sea duplicada, la respuesta en la otra pregunta no es ni rápida ni bonita. Transforma la matriz en una lista de arrays (a mano). – f1v3

Respuesta

199

usted podría utilizar ArrayUtils de bienes comunes lang.

array = ArrayUtils.removeElement(array, element) 

commons.apache.org library:Javadocs

+0

¿Hay una guayaba equivalente a esto? –

+1

@Clive Guava parece funcionar solo en colecciones. –

+2

¿esto reduce la matriz también? –

35

No se puede eliminar un elemento de la matriz básica de Java. Eche un vistazo a varias colecciones y ArrayList en su lugar.

+0

lo sé, solo quiero una hermosa apariencia con arraylist o algo así. así, ¿alguna pista para eso? – Tobias

+0

+1: Use LinkedList, la vida es más simple. –

+6

LinkedList rara vez es una buena idea. La intrrface de List le otorga acceso aleatorio, pero LinkedList le da O (n) tiempos de acceso en lugar de O (1). –

-5

Seguro, crear otra matriz :)

14

Niza solución en busca sería utilizar una lista en lugar de la matriz en el primer lugar.

List.remove(index) 

Si usted tiene utilizar matrices, dos llamadas a System.arraycopy lo más probable es ser el más rápido.

Foo[] result = new Foo[source.length - 1]; 
System.arraycopy(source, 0, result, 0, index); 
if (source.length != index) { 
    System.arraycopy(source, index + 1, result, index, source.length - index - 1); 
} 

(Arrays.asList también es un buen candidato para trabajar con matrices, pero no parece apoyar remove.)

+1

+1: usa LinkedList o ArrayList. –

-3

Utilice un ArrayList:

alist.remove(1); //removes the element at position 1 
0

espero que utiliza el coleccion java/colecciones java comunes!

Con una java.util.ArrayList se pueden hacer cosas como la siguiente:

yourArrayList.remove(someObject); 

yourArrayList.add(someObject); 
+2

Una matriz no es una colección ... – Nicolas

+0

¡Pero la mayoría de las colecciones son matrices! Ver: http://en.wikipedia.org/wiki/Array –

+1

Sí, pero esta pregunta está etiquetada con java y, en java, una matriz no es una colección ... – Nicolas

0

Copy la matriz original en otra matriz, sin el elemento a eliminar.

Una forma simplificada de hacerlo es utilizar una lista, establecer ... y utilizar el método remove().

0

Cambie el elemento que se va a eliminar con el último elemento, si no le interesa cambiar el tamaño de la matriz.

+2

Esto rompería las cosas si la matriz se ordenó antes de la eliminación. – eleven81

1

bien, THX mucho Ahora uso algo como esto:

public static String[] removeElements(String[] input, String deleteMe) { 
    if (input != null) { 
     List<String> list = new ArrayList<String>(Arrays.asList(input)); 
     for (int i = 0; i < list.size(); i++) { 
      if (list.get(i).equals(deleteMe)) { 
       list.remove(i); 
      } 
     } 
     return list.toArray(new String[0]); 
    } else { 
     return new String[0]; 
    } 
} 
+0

Si realmente necesita dejar la matriz inicial sin cambios, será mejor que cree una lista vacía y la complete con los elementos correctos en lugar de hacerlo de esta manera. – Nicolas

+0

No estoy seguro de que esto sea lo que la gente tenía en mente cuando sugirieron usar colecciones, pero en cualquier caso, tenga cuidado con esos índices de listas. Parece que estás salteando el elemento inmediatamente después de eliminarlo (prueba {"a", "b", "deleteMe", "deleteMe", "c"}). –

36

La mejor opción sería utilizar una colección, pero si es por alguna razón, utilice arraycopy. Puede usarlo para copiar desde y hacia la misma matriz con un desplazamiento ligeramente diferente.

Por ejemplo:

public void removeElement(Object[] arr, int removedIdx) { 
    System.arraycopy(arr, removedIdx + 1, arr, removedIdx, arr.length - 1 - removedIdx); 
} 

Editar en respuesta al comentario:

No es otra buena manera, es realmente la única manera aceptable.

Para asignar una colección (crea una nueva matriz), luego eliminar un elemento (que la colección hará usando arraycopy) luego llamar a Array en ella (crea una SEGUNDA nueva matriz) para cada eliminación nos lleva al punto donde está no es un problema de optimización, es una programación criminalmente mala.

Supongamos que tiene una matriz ocupando, digamos, 100 mb de memoria RAM. Ahora desea iterar sobre él y eliminar 20 elementos.

darle una oportunidad ...

Sé que asumir que no va a ser tan grande, o que si estuviera borrando que muchos a la vez que le codificar de manera diferente, pero me he fijado una gran cantidad de código donde alguien hizo suposiciones como esa.

+2

Después de una "eliminación" (es decir, cambiar la matriz dejada por un elemento) ¿no habrá un duplicado del elemento final? es decir, a.length será el mismo después de la eliminación, ¿no? No digo que no me gusta la idea, solo que uno debe ser consciente de esto. – Adamski

+0

+1. Esto funciona para mis propósitos. (Resolví el pequeño problema que tenías en tu muestra. Espero que no te importe.) – Gunslinger47

+0

Sí, esto solo desplazará los elementos que quedan y seguirá habiendo el último elemento presente. Tenemos que usar una nueva matriz para copiar. – Reddy

44

Su pregunta no es muy clara. Desde su propia respuesta, puedo decir mejor lo que está tratando de hacer:

public static String[] removeElements(String[] input, String deleteMe) { 
    List result = new LinkedList(); 

    for(String item : input) 
     if(!deleteMe.equals(item)) 
      result.add(item); 

    return result.toArray(input); 
} 

NB: Esto no se ha probado. La comprobación de errores se deja como un ejercicio para el lector (lanzaría IllegalArgumentException si input o deleteMe son nulos, una lista vacía en la lista nula no tiene sentido. Eliminar cadenas nulas de la matriz podría tener sentido, pero yo ' ll dejar que como un ejercicio demasiado, en la actualidad, se generará un NPE cuando se trata de llamar es igual en DeleteMe si DeleteMe es nulo)

elecciones que hice aquí:

he usado un LinkedList.. La iteración debe ser igual de rápida, y evita cualquier cambio de tamaño, o asigna una lista demasiado grande si termina eliminando muchos elementos. Puede usar una ArrayList y establecer el tamaño inicial a la longitud de entrada. Es probable que no haga mucha diferencia.

+2

Tenga en cuenta que querrá usar el resultado 'List '. Cuando hago esto en el compilador actual, el comando toArray arroja un error de tipo (la otra solución es emitir el resultado). –

4

Puede usar el ArrayUtils API para eliminarlo de una "forma atractiva". Implementa muchas operaciones (eliminar, encontrar, agregar, contener, etc.) en Arrays.
Echa un vistazo. Ha hecho mi vida más simple.

8

Creo que la pregunta era pedir una solución sin el uso de la API de Colecciones. Uno usa arreglos ya sea para detalles de bajo nivel, donde el rendimiento importa, o para una integración de SOA débilmente acoplada. En lo posterior, está bien convertirlos en Colecciones y pasarlos a la lógica de negocios como tal.

Para las funciones de bajo nivel de rendimiento, por lo general ya está oscurecido por el estado imperativo rápido y sucio: mezcla de bucles for, etc. En ese caso, la conversión entre colecciones y matrices es engorrosa, ilegible y incluso intensivo en recursos.

Por cierto, TopCoder, ¿alguien? ¡Siempre esos parámetros de matriz! Así que prepárate para poder manejarlos cuando estés en la Arena.

A continuación se muestra mi interpretación del problema y una solución. Es diferente en funcionalidad de los dos dados por Bill K y jelovirt. Además, maneja con gracia el caso cuando el elemento no está en la matriz.

Espero que ayude! Se necesitan

public char[] remove(char[] symbols, char c) 
{ 
    for (int i = 0; i < symbols.length; i++) 
    { 
     if (symbols[i] == c) 
     { 
      char[] copy = new char[symbols.length-1]; 
      System.arraycopy(symbols, 0, copy, 0, i); 
      System.arraycopy(symbols, i+1, copy, i, symbols.length-i-1); 
      return copy; 
     } 
    } 
    return symbols; 
} 
+1

Esto funciona perfectamente. – Reddy

+1

Genial. Demasiadas respuestas respondiendo una pregunta diferente a OP's. –

2

Algunos más condiciones previas para las escritas por Bill K y dadinn

Object[] newArray = new Object[src.length - 1]; 
if (i > 0){ 
    System.arraycopy(src, 0, newArray, 0, i); 
    } 

if (newArray.length > i){ 
     System.arraycopy(src, i + 1, newArray, i, newArray.length - i); 
    } 

    return newArray; 
3

No se puede cambiar la longitud de una matriz, pero se pueden cambiar los valores del índice Declara, por copiando nuevos valores y almacenándolos en un número de índice existente. 1 = mike, 2 = jeff // 10 = george 11 pasa a 1 sobreescribir mike.

Object[] array = new Object[10]; 
    int count=-1; 

    public void myFunction(String string) { 
     count++; 
     if(count == array.length) { 
      count = 0; // overwrite first 
     } 
     array[count] = string;  
    } 
+1

¡Creo que señalar que la longitud de una matriz no se puede cambiar es un detalle importante! –

Cuestiones relacionadas