Domanda

Data una matrice di n oggetti, diciamo che è una matrice di stringhe e ha i seguenti valori:

foo[0] = "a";
foo[1] = "cc";
foo[2] = "a";
foo[3] = "dd";

Cosa devo fare per eliminare / rimuovere tutte le stringhe / oggetti pari a " a " nell'array?

È stato utile?

Soluzione

[Se vuoi un codice pronto per l'uso, scorri fino al mio " Modifica3 " (dopo il taglio). Il resto è qui per i posteri.]

Rafforzare L'idea di Dustman :

List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(array);

Modifica: ora sto usando Arrays.asList invece di Collections.singleton : singleton è limitato a una voce, mentre asList approccio ti consente di aggiungere altre stringhe per filtrare in seguito: Arrays.asList (" a " ;, " b " ;, " c ") .

Modifica2: l'approccio sopra mantiene lo stesso array (quindi l'array ha ancora la stessa lunghezza); l'elemento dopo l'ultimo è impostato su null. Se vuoi un nuovo array dimensionato esattamente come richiesto, usa questo invece:

array = list.toArray(new String[0]);

Modifica3: se usi questo codice su base frequente nella stessa classe, ti consigliamo di aggiungere questo alla tua classe:

private static final String[] EMPTY_STRING_ARRAY = new String[0];

Quindi la funzione diventa:

List<String> list = new ArrayList<>();
Collections.addAll(list, array);
list.removeAll(Arrays.asList("a"));
array = list.toArray(EMPTY_STRING_ARRAY);

Questo smetterà quindi di sporcare il tuo heap con inutili array di stringhe vuote che sarebbero altrimenti new ogni volta che la tua funzione viene chiamata.

Il suggerimento di cynicalman (vedi commenti) aiuterà anche con i rifiuti del mucchio, e per correttezza dovrei menzionarlo:

array = list.toArray(new String[list.size()]);

Preferisco il mio approccio, perché potrebbe essere più facile sbagliare la dimensione esplicita (ad esempio, chiamando size () nell'elenco sbagliato).

Altri suggerimenti

Un'alternativa in Java 8:

String[] filteredArray = Arrays.stream(array)
    .filter(e -> !e.equals(foo)).toArray(String[]::new);

Crea un List dall'array con Arrays.asList () e chiama remove () su tutti gli elementi appropriati. Quindi chiama toArray () su 'Elenco' per tornare nuovamente in un array.

Non terribilmente performante, ma se lo incapsuli correttamente, puoi sempre fare qualcosa di più veloce in seguito.

Puoi sempre fare:

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);

Puoi usare una libreria esterna:

org.apache.commons.lang.ArrayUtils.remove(java.lang.Object[] array, int index)

È nel progetto Apache Commons Lang http://commons.apache.org/lang/

Vedi il codice qui sotto

ArrayList<String> a = new ArrayList<>(Arrays.asList(strings));
a.remove(i);
strings = new String[a.size()];
a.toArray(strings);

Se è necessario rimuovere più elementi dall'array senza convertirlo in Elenco né creare un array aggiuntivo, è possibile farlo in O (n) senza dipendere dal numero di elementi da rimuovere.

Qui a è un array iniziale, int ... r sono indici (posizioni) distinti di elementi da rimuovere:

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"
}  

Piccoli test:

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]

Nella tua attività, puoi prima scansionare l'array per raccogliere posizioni di " a " ;, quindi chiamare removeItems () .

Qualcosa nel creare un elenco di esso quindi rimuoverlo e poi tornare a un array mi sembra sbagliato. Non ho ancora testato, ma penso che quanto segue funzionerà meglio. Sì, probabilmente sto pre-ottimizzando indebitamente.

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];
   }
}

Mi rendo conto che questo è un post molto vecchio, ma alcune delle risposte qui mi hanno aiutato, quindi ecco la mia tuppence 'ha'penny's worth!

Ho faticato a farlo funzionare per un po 'di tempo prima di modificare la necessità di ridimensionare l'array in cui sto riscrivendo, a meno che le modifiche apportate a ArrayList lasciano invariate le dimensioni dell'elenco .

Se il ArrayList che stai modificando finisce con un numero maggiore o minore di elementi rispetto a quello con cui è iniziato, la riga List.toArray () causerà un'eccezione, quindi hai bisogno di qualcosa come List.toArray (new String [] {}) o List.toArray (new String [0]) per creare un array con il nuovo ( dimensioni corrette).

Sembra ovvio ora che lo so. Non è così ovvio per un principiante Android / Java che si sta avvicinando a costrutti di codice nuovi e sconosciuti e non ovvio da alcuni dei precedenti post qui, quindi volevo solo chiarire questo punto a chiunque si grattasse la testa per ore come ero !

Ci sono molte risposte qui - il problema a mio modo di vedere è che non hai detto PERCHÉ stai usando un array invece di una raccolta, quindi lasciami suggerire un paio di ragioni e quali soluzioni applicare (La maggior parte delle soluzioni hanno già ricevuto risposta in altre domande qui, quindi non entrerò in troppi dettagli):

motivo: non sapevi che esistesse il pacchetto di raccolta o non ti fidi di esso

soluzione: usa una raccolta.

Se si prevede di aggiungere / eliminare dal centro, utilizzare un elenco di collegamenti. Se sei davvero preoccupato per le dimensioni o spesso indicizzi nel mezzo della raccolta, usa una ArrayList. Entrambi dovrebbero avere operazioni di eliminazione.

motivo: sei preoccupato per le dimensioni o desideri il controllo sull'allocazione della memoria

soluzione: utilizzare un ArrayList con una dimensione iniziale specifica.

Un ArrayList è semplicemente un array che può espandersi, ma non è sempre necessario farlo. Sarà molto intelligente aggiungere / rimuovere elementi, ma di nuovo se stai inserendo / rimuovendo un LOTTO dal centro, usa un Elenco collegato.

motivo: hai un array in arrivo e un array in uscita, quindi vuoi operare su un array

soluzione: convertilo in una ArrayList, elimina l'elemento e riconvertilo

motivo: pensi di poter scrivere un codice migliore se lo fai da solo

soluzione: impossibile, utilizzare un array o un elenco collegato.

motivo: si tratta di un compito di classe e non sei autorizzato o non hai accesso alle API della raccolta per qualche motivo

presupposto: è necessario che il nuovo array abbia la "dimensione" corretta

soluzione: Esegui la scansione dell'array per individuare gli elementi corrispondenti e contali. Crea un nuovo array della dimensione corretta (dimensione originale - numero di corrispondenze). utilizzare System.arraycopy ripetutamente per copiare ogni gruppo di elementi che si desidera conservare nel nuovo array. Se questo è un compito di classe e non puoi usare System.arraycopy, copiali uno alla volta a mano in un ciclo, ma non farlo mai nel codice di produzione perché è molto più lento. (Queste soluzioni sono entrambe dettagliate in altre risposte)

motivo: devi eseguire bare metal

presupposto: NON DEVI assegnare spazio inutilmente o impiegare troppo tempo

ipotesi: stai monitorando le dimensioni utilizzate nell'array (lunghezza) separatamente perché altrimenti dovresti riallocare l'array per eliminare / inserire.

Un esempio del motivo per cui potresti voler fare questo: un singolo array di primitivi (diciamo valori int) sta prendendo una parte significativa del tuo ariete - come il 50%! Un ArrayList li forzerebbe in un elenco di puntatori a oggetti Integer che userebbero alcune volte quella quantità di memoria.

soluzione: Iterate sul tuo array e ogni volta che trovi un elemento da rimuovere (chiamiamolo elemento n), usa System.arraycopy per copiare la coda dell'array sul " cancellato " element (Source e Destination sono lo stesso array): è abbastanza intelligente eseguire la copia nella direzione corretta in modo che la memoria non si sovrascriva da sola:

 System.arraycopy(ary, n+1, ary, n, length-n) 
 length--;

Probabilmente vorrai essere più intelligente di così se stai eliminando più di un elemento alla volta. Sposteresti l'area solo tra una "corrispondenza". e la successiva anziché l'intera coda e, come sempre, evitare di spostare due pezzi qualsiasi

In quest'ultimo caso, devi assolutamente fare tu stesso il lavoro e usare System.arraycopy è davvero l'unico modo per farlo poiché sceglierà il modo migliore per spostare la memoria per l'architettura del tuo computer - dovrebbe essere molte volte più veloce di qualsiasi codice che potresti ragionevolmente scrivere da solo.

EDIT:

Il punto con i null nell'array è stato cancellato. Ci scusiamo per i miei commenti.

originale:

Ehm ... la linea

array = list.toArray(array);

sostituisce tutti gli spazi vuoti nell'array in cui l'elemento rimosso è stato con null . Questo potrebbe essere pericoloso , perché gli elementi vengono rimossi, ma la lunghezza dell'array rimane la stessa!

Se si desidera evitare ciò, utilizzare un nuovo array come parametro per toArray (). Se non vuoi usare removeAll, un Set sarebbe un'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));

si ottiene:

[a, bc, dc, a, ef]
[dc, ef, bc]

Dove viene emessa l'attuale risposta accettata da Chris Yester Young:

[a, bc, dc, a, ef]
[bc, dc, ef, null, ef]

con il codice

    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));

senza alcun valore nullo lasciato indietro.

Il mio piccolo contributo a questo 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;
}

}

Matrice iniziale

   int[] array = {5,6,51,4,3,2};

se si desidera rimuovere 51 ovvero l'indice 2, utilizzare il seguente

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

Dipende da cosa intendi per " rimuovi " ;? Un array è un costrutto di dimensioni fisse: non è possibile modificare il numero di elementi al suo interno. Quindi è possibile a) creare un nuovo array più corto senza gli elementi che non si desidera oppure b) assegnare le voci che non si desidera a qualcosa che indica il loro stato "vuoto"; di solito null se non lavori con le primitive.

Nel primo caso creare un Elenco dall'array, rimuovere gli elementi e creare un nuovo array dall'elenco. Se le prestazioni sono importanti, scorrere sull'array assegnando tutti gli elementi che non devono essere rimossi in un elenco, quindi creare un nuovo array dall'elenco. Nel secondo caso è sufficiente passare e assegnare null alle voci dell'array.

Arrgh, non riesco a visualizzare correttamente il codice. Scusa, l'ho fatto funzionare. Scusami ancora, non credo di aver letto correttamente la domanda.

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++;
    }
}

Copia tutti gli elementi tranne quello con indice 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) );
            }

In una serie di stringhe come

String name = 'a b c d e a f b d e' // potrebbe essere come String name = 'aa bb c d e aa f bb d e'

Costruisco la seguente classe

class clearname{
def parts
def tv
public def str = ''
String name
clearname(String name){
    this.name = name
    this.parts = this.name.split(" ")
    this.tv = this.parts.size()
}
public String cleared(){

        int i
        int k
        int j=0        
    for(i=0;i<tv;i++){
        for(k=0;k<tv;k++){
            if(this.parts[k] == this.parts[i] && k!=i){
               this.parts[k] = '';
                j++
            }
        }
    }
    def str = ''
    for(i=0;i<tv;i++){
        if(this.parts[i]!='')

           this.str += this.parts[i].trim()+' '
    } 
    return this.str    
}}



return new clearname(name).cleared()

ottenere questo risultato

a b c d e f

spero che questo codice aiuti chiunque Saluti

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.

Usa:

list.removeAll(...);
//post what char you need in the ... section

Assegna null ai percorsi dell'array.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top