from - ¿Cómo elimino objetos de una matriz en Java?
remove array java (18)
Algo acerca de hacer una lista de ello, luego eliminar y luego volver a una matriz me parece erróneo. No he probado, pero creo que los siguientes tendrán un mejor rendimiento. Sí, probablemente estoy optimizando demasiado.
boolean [] deleteItem = new boolean[arr.length];
int size=0;
for(int i=0;i<arr.length;i==){
if(arr[i].equals("a")){
deleteItem[i]=true;
}
else{
deleteItem[i]=false;
size++;
}
}
String[] newArr=new String[size];
int index=0;
for(int i=0;i<arr.length;i++){
if(!deleteItem[i]){
newArr[index++]=arr[i];
}
}
Dado un conjunto de n Objetos, digamos que es una matriz de cadenas , y tiene los siguientes valores:
foo[0] = "a";
foo[1] = "cc";
foo[2] = "a";
foo[3] = "dd";
¿Qué debo hacer para eliminar / eliminar todas las cadenas / objetos igual a "a" en la matriz?
Aquí hay muchas respuestas; el problema es que no dijiste POR QUÉ estás usando una matriz en lugar de una colección, así que sugiero un par de razones y qué soluciones se aplicarían (la mayoría de las soluciones). ya se han respondido en otras preguntas aquí, así que no entraré en demasiados detalles):
razón: usted no sabía que el paquete de recolección existía o no confiaba en él
solución: use una colección.
Si planea agregar / eliminar desde el medio, use una LinkedList. Si está realmente preocupado por el tamaño o, a menudo, indexa justo en el medio de la colección, use una ArrayList. Ambos deberían tener operaciones de eliminación.
razón: le preocupa el tamaño o quiere controlar la asignación de memoria
solución: use una ArrayList con un tamaño inicial específico.
Una ArrayList es simplemente una matriz que puede expandirse, pero no siempre tiene que hacerlo. Será muy inteligente agregar / eliminar elementos, pero nuevamente si está insertando / eliminando un LOTE desde el medio, use una Lista Vinculada.
razón: tiene una matriz entrando y una matriz saliendo, por lo que desea operar en una matriz
solución: Convierta a ArrayList, elimine el elemento y conviértalo de nuevo
razón: crees que puedes escribir un código mejor si lo haces tú mismo
solución: no puede, use una matriz o una lista vinculada.
razón: esta es una tarea de clase y no está permitido o no tiene acceso a la colección por alguna razón
Asunción: necesita que la nueva matriz sea del "tamaño" correcto
solución: Escanee la matriz para buscar elementos que coincidan y cuéntelos. Cree una nueva matriz del tamaño correcto (tamaño original - número de coincidencias). use System.arraycopy varias veces para copiar cada grupo de elementos que desea conservar en su nueva matriz. Si se trata de una asignación de clase y no puede usar System.arraycopy, simplemente cópielos uno por uno a mano en un bucle, pero nunca haga esto en el código de producción porque es mucho más lento. (Estas soluciones se detallan en otras respuestas)
razón: necesitas ejecutar bare metal
suposición: NO DEBE asignar espacio innecesariamente o tomar demasiado tiempo
Asunción: está rastreando el tamaño utilizado en la matriz (longitud) por separado porque de lo contrario tendría que reasignar su matriz para eliminar / insertar.
Un ejemplo de por qué es posible que desee hacer esto: una sola matriz de primitivas (digamos valores int) está tomando una porción significativa de su ram - ¡como el 50%! Un ArrayList forzaría estos en una lista de punteros a objetos enteros que usarían algunas veces esa cantidad de memoria.
Solución: itere sobre su matriz y cada vez que encuentre un elemento para eliminar (llamémosle elemento n), use System.arraycopy para copiar la cola de la matriz sobre el elemento "eliminado" (la fuente y el destino son la misma matriz). es lo suficientemente inteligente como para hacer la copia en la dirección correcta para que la memoria no se sobrescriba sola:
System.arraycopy(ary, n+1, ary, n, length-n) length--;
Probablemente quiera ser más inteligente que esto si está eliminando más de un elemento a la vez. Solo movería el área entre una "coincidencia" y la siguiente en lugar de toda la cola y, como siempre, evite mover cualquier trozo dos veces.
En este último caso, debe hacer el trabajo usted mismo, y usar System.arraycopy es realmente la única forma de hacerlo, ya que va a elegir la mejor manera de mover la memoria para la arquitectura de su computadora, debe ser mucho más rápido. que cualquier código que razonablemente podría escribir usted mismo.
Arrgh, no puedo hacer que el código se muestre correctamente. Lo siento, lo tengo funcionando. Perdón otra vez, no creo haber leído la pregunta correctamente.
String foo[] = {"a","cc","a","dd"},
remove = "a";
boolean gaps[] = new boolean[foo.length];
int newlength = 0;
for (int c = 0; c<foo.length; c++)
{
if (foo[c].equals(remove))
{
gaps[c] = true;
newlength++;
}
else
gaps[c] = false;
System.out.println(foo[c]);
}
String newString[] = new String[newlength];
System.out.println("");
for (int c1=0, c2=0; c1<foo.length; c1++)
{
if (!gaps[c1])
{
newString[c2] = foo[c1];
System.out.println(newString[c2]);
c2++;
}
}
Asignar nulo a las ubicaciones de la matriz.
Copiará todos los elementos excepto el que tiene el índice i:
if(i == 0){
System.arraycopy(edges, 1, copyEdge, 0, edges.length -1 );
}else{
System.arraycopy(edges, 0, copyEdge, 0, i );
System.arraycopy(edges, i+1, copyEdge, i, edges.length - (i+1) );
}
Depende de lo que quiere decir con "eliminar"? Una matriz es una construcción de tamaño fijo; no puede cambiar la cantidad de elementos en ella. Por lo tanto, puede a) crear una matriz nueva, más corta, sin los elementos que no desea o b) asignar las entradas que no desea a algo que indique su estado ''vacío''; generalmente nulo si no está trabajando con primitivos.
En el primer caso, cree una lista de la matriz, elimine los elementos y cree una nueva matriz de la lista. Si el rendimiento es importante, repita la matriz asignando elementos que no deberían eliminarse a una lista y luego cree una nueva matriz de la lista. En el segundo caso, simplemente pase y asigne nulo a las entradas de la matriz.
EDITAR:
El punto con los nulos en la matriz se ha despejado. Perdón por mis comentarios
Original:
Ehm ... la línea
array = list.toArray(array);
reemplaza todos los espacios en la matriz donde el elemento eliminado ha estado con nulo . Esto podría ser peligroso , porque los elementos se eliminan, ¡pero la longitud de la matriz sigue siendo la misma!
Si desea evitar esto, use un nuevo Array como parámetro para toArray (). Si no quiere usar removeAll, un Set sería una alternativa:
String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };
System.out.println(Arrays.toString(array));
Set<String> asSet = new HashSet<String>(Arrays.asList(array));
asSet.remove("a");
array = asSet.toArray(new String[] {});
System.out.println(Arrays.toString(array));
Da:
[a, bc, dc, a, ef]
[dc, ef, bc]
Donde como la respuesta aceptada actual de Chris Yester Young produce:
[a, bc, dc, a, ef]
[bc, dc, ef, null, ef]
con el código
String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };
System.out.println(Arrays.toString(array));
List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(array);
System.out.println(Arrays.toString(array));
sin ningún valor nulo dejado atrás.
Haga una List
de la matriz con Arrays.asList()
y llame a remove()
en todos los elementos apropiados. Luego, llame a toArray()
en la ''Lista'' para volver a hacer una matriz.
No es muy eficiente, pero si lo encapsula adecuadamente, siempre puede hacer algo más rápido más adelante.
Me doy cuenta de que esta es una publicación muy antigua, pero algunas de las respuestas aquí me ayudaron, así que aquí está el valor de mi tuppence ''ha''penny!
Tuve problemas para conseguir que esto funcione durante bastante tiempo antes de pensar que el arreglo en el que estoy escribiendo debería ser redimensionado, a menos que los cambios realizados en ArrayList
no cambien el tamaño de la lista.
Si ArrayList
que está modificando termina con más o menos elementos de los que comenzó, la línea List.toArray()
causará una excepción, por lo que necesita algo como List.toArray(new String[] {})
o List.toArray(new String[0])
para crear una matriz con el nuevo tamaño (correcto).
Suena obvio ahora que lo sé. No es tan obvio para un novato de Android / Java que se está familiarizando con construcciones de código nuevas y desconocidas y no es obvio en algunas de las publicaciones anteriores aquí, así que quería dejar este punto claro para que nadie más se rascara la cabeza durante horas como yo !
Mi pequeña contribución a este problema.
public class DeleteElementFromArray {
public static String foo[] = {"a","cc","a","dd"};
public static String search = "a";
public static void main(String[] args) {
long stop = 0;
long time = 0;
long start = 0;
System.out.println("Searched value in Array is: "+search);
System.out.println("foo length before is: "+foo.length);
for(int i=0;i<foo.length;i++){ System.out.println("foo["+i+"] = "+foo[i]);}
System.out.println("==============================================================");
start = System.nanoTime();
foo = removeElementfromArray(search, foo);
stop = System.nanoTime();
time = stop - start;
System.out.println("Equal search took in nano seconds = "+time);
System.out.println("==========================================================");
for(int i=0;i<foo.length;i++){ System.out.println("foo["+i+"] = "+foo[i]);}
}
public static String[] removeElementfromArray( String toSearchfor, String arr[] ){
int i = 0;
int t = 0;
String tmp1[] = new String[arr.length];
for(;i<arr.length;i++){
if(arr[i] == toSearchfor){
i++;
}
tmp1[t] = arr[i];
t++;
}
String tmp2[] = new String[arr.length-t];
System.arraycopy(tmp1, 0, tmp2, 0, tmp2.length);
arr = tmp2; tmp1 = null; tmp2 = null;
return arr;
}
}
Puedes usar la biblioteca externa:
org.apache.commons.lang.ArrayUtils.remove(java.lang.Object[] array, int index)
Está en el proyecto Apache Commons Lang http://commons.apache.org/lang/
Si necesita eliminar varios elementos de la matriz sin convertirla en List
ni crear una matriz adicional, puede hacerlo en O (n), sin depender del recuento de elementos que desea eliminar.
Aquí, a
es una matriz inicial, int... r
son distintos índices ordenados (posiciones) de elementos para eliminar:
public int removeItems(Object[] a, int... r) {
int shift = 0;
for (int i = 0; i < a.length; i++) {
if (shift < r.length && i == r[shift]) // i-th item needs to be removed
shift++; // increment `shift`
else
a[i - shift] = a[i]; // move i-th item `shift` positions left
}
for (int i = a.length - shift; i < a.length; i++)
a[i] = null; // replace remaining items by nulls
return a.length - shift; // return new "length"
}
Pruebas pequeñas:
String[] a = {"0", "1", "2", "3", "4"};
removeItems(a, 0, 3, 4); // remove 0-th, 3-rd and 4-th items
System.out.println(Arrays.asList(a)); // [1, 2, null, null, null]
En su tarea, primero puede escanear el arreglo para recolectar posiciones de "a", luego llamar a removeItems()
.
Siempre puedes hacer:
int i, j;
for (i = j = 0; j < foo.length; ++j)
if (!"a".equals(foo[j])) foo[i++] = foo[j];
foo = Arrays.copyOf(foo, i);
Una alternativa en Java 8:
String[] filteredArray = Arrays.stream(array)
.filter(e -> !e.equals(foo)).toArray(String[]::new);
Utilizar:
list.removeAll(...);
//post what char you need in the ... section
Ver el código a continuación
ArrayList<String> a = new ArrayList<>(Arrays.asList(strings));
a.remove(i);
strings = new String[a.size()];
a.toArray(strings);
[Si desea un código listo para usar, desplácese a mi "Editar3" (después del corte). El resto está aquí para la posteridad.]
Para dar cuerpo a la idea de Dustman :
List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(array);
Editar: ahora estoy usando Arrays.asList
lugar de Collections.singleton
: singleton está limitado a una entrada, mientras que el enfoque asList
permite agregar otras cadenas para filtrar más adelante: Arrays.asList("a", "b", "c")
.
Edit2: el enfoque anterior conserva la misma matriz (por lo que la matriz sigue siendo la misma longitud); el elemento después de la última se establece en nulo. Si desea una nueva matriz de tamaño exactamente como se requiere, use esto en su lugar:
array = list.toArray(new String[0]);
Editar3: si utiliza este código con frecuencia en la misma clase, puede considerar agregar esto a su clase:
private static final String[] EMPTY_STRING_ARRAY = new String[0];
Entonces la función se convierte en:
List<String> list = new ArrayList<>();
Collections.addAll(list, array);
list.removeAll(Arrays.asList("a"));
array = list.toArray(EMPTY_STRING_ARRAY);
Esto dejará de ensuciar tu montón con matrices de cadenas vacías inútiles que, de otro modo, serían ed new
cada vez que se llame a tu función.
La sugerencia de cínico (ver comentarios) también ayudará con el montón de basura, y para ser justos debería mencionarlo:
array = list.toArray(new String[list.size()]);
Prefiero mi enfoque, porque puede ser más fácil equivocar el tamaño explícito (p. Ej., Llamar al size()
en la lista incorrecta).
class sd
{
public static void main(String[ ] args)
{
System.out.println("Search and Delete");
int key;
System.out.println("Enter the length of array:");
Scanner in=new Scanner(System.in);
int n=in.nextInt();
int numbers[]=new int[n];
int i = 0;
boolean found = false;
System.out.println("Enter the elements in Array :");
for ( i = 0; i < numbers.length; i++)
{
numbers[i]=in.nextInt();
}
System.out.println("The elements in Array are:");
for ( i = 0; i < numbers.length; i++)
{
System.out.println(numbers[i]);
}
System.out.println("Enter the element to be searched:");
key=in.nextInt();
for ( i = 0; i < numbers.length; i++)
{
if (numbers[ i ] == key)
{
found = true;
break;
}
}
if (found)
{
System.out.println("Found " + key + " at index " + i + ".");
numbers[i]=0;//haven''t deleted the element in array
System.out.println("After Deletion:");
for ( i = 0; i < numbers.length; i++)
{
if (numbers[ i ]!=0)
{ //it skips displaying element in array
System.out.println(numbers[i]);
}
}
}
else
{
System.out.println(key + "is not in this array.");
}
}
}//Sorry.. if there are mistakes.