Frage

ein Array von Bei n Objekte, lassen Sie uns sagen, es ist ein Array von Strings , und es hat die folgenden Werte:

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

Was muss ich tun, um alle Saiten zu löschen / entfernen / Objekte gleich "a" im Array?

War es hilfreich?

Lösung

[Wenn Sie einige ready-to-use-Code, blättern Sie bitte meine "Edit3" (nach dem Schnitt). Der Rest ist hier für die Nachwelt.]

Um zu konkretisieren Dustman Idee :

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

Edit: Ich verwende jetzt Arrays.asList statt Collections.singleton: Singletons auf einen Eintrag beschränkt ist, während der asList Ansatz Sie können andere Zeichenfolgen hinzuzufügen später heraus zu filtern. Arrays.asList("a", "b", "c")

Edit2: Der obige Ansatz behält die gleiche Array (so das Array ist immer noch die gleiche Länge); das Element nach dem letzten wird auf null gesetzt. Wenn Sie ein möchten neue Array genau sized nach Bedarf verwenden Sie stattdessen:

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

Edit3: Wenn Sie diesen Code in regelmäßigen Abständen in der gleichen Klasse verwenden, können Sie möchten, diese zu Ihrer Klasse zu berücksichtigen:

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

Dann ist die Funktion wird:

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

Dies wird dann stoppen Sie den Haufen mit nutzlosem leeren String-Arrays Littering, die sonst jedes Mal Ihrer Funktion aufgerufen wird newed würden.

cynicalman Vorschlag (siehe Kommentare) wird auch mit dem Heap Littering helfen, und für Fairness soll ich erwähne es:

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

ziehe ich mein Ansatz, weil es möglicherweise einfacher, die explizite Größe zu erhalten falsch (z.B. size() auf der falschen Liste aufrufen).

Andere Tipps

Eine Alternative in Java 8:

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

Erstellen Sie eine List aus dem Array mit Arrays.asList() und rufen remove() auf allen entsprechenden Elemente. Dann toArray() auf der ‚Liste‘ ruft wieder zurück in ein Array zu machen.

Nicht besonders performant, aber wenn man es richtig einkapseln, können Sie immer schneller tun etwas später.

Sie können immer tun:

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

Sie können die externe Bibliothek verwenden:

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

Es ist in Projekt Apache Commons Lang http://commons.apache.org/lang/

Siehe Code unten

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

Wenn Sie mehrere Elemente aus dem Array entfernen müssen ohne Umwandlung in List noch zusätzliche Array erstellen, können Sie es in O tun können (n) nicht abhängig von Anzahl der Elemente zu entfernen.

Dabei ist a Ausgangsanordnung, int... r unterscheiden geordneten Indizes (Positionen) der Elemente zu entfernen:

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

Kleine Prüfung:

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]

Ihre Aufgabe können Sie erste Array-Scan-Positionen von „a“ zu sammeln, dann removeItems() nennen.

Etwas über die Machen Sie eine Liste dann dann auf ein Array entfernen zurück, scheint mir falsch. Nicht getestet, aber ich denke, die folgenden besser abschneiden wird. Ja, ich bin wahrscheinlich übermäßig vorge Optimierung.

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

Ich weiß, dies ist eine sehr alte Post, aber einige der Antworten hier half mir aus, so ist hier meine tuppence‘ha'penny wert!

Ich kämpfte dies immer noch eine ganze Weile zu arbeiten, bevor vor twigging, dass das Array, das ich wieder in gebraucht werde das Schreiben der Größe verändert werden, es sei denn, die Änderungen an der ArrayList die Liste Größe unverändert lassen.

Wenn die ArrayList, die Sie endet mit mehr oder weniger Elemente sind zu modifizieren, als es begann mit, wird die Linie List.toArray() eine Ausnahme verursachen, so dass Sie so etwas wie List.toArray(new String[] {}) oder List.toArray(new String[0]) benötigen, um ein Array mit dem neuen zu erstellen (richtig ) Größe.

Sounds jetzt klar, dass ich es weiß. Nicht so offensichtlich zu einem Android / Java-Neuling, der mit neuen und unbekannten Code-Konstrukten in dem Griff wird immer und nicht auf der Hand von einigen der früheren Beiträge hier, so wollte nur diesen Punkt machen wirklich klar für jemanden anderen ihre Köpfe stundenlang kratzen, wie ich war !

Es gibt viele Antworten hier - das Problem, wie ich es sehe, ist, dass Sie nicht sagen, warum Sie ein Array anstelle einer Sammlung verwenden, so lassen Sie mich ein paar Gründe vorschlagen und welche Lösungen gelten würde (Most die Lösungen haben sie hier bereits in anderen Fragen beantwortet worden, so dass ich nicht zu sehr ins Detail gehen):

Grund: Sie wussten nicht, die Sammlung Paket existiert oder sie nicht vertrauen

Lösung: eine Sammlung verwenden.

Wenn Sie auf das Hinzufügen / Löschen von der Mitte zu planen, verwenden Sie eine LinkedList. Wenn Sie wirklich besorgt über die Größe oder oft Index rechts in die Mitte der Sammlung eine Arraylist verwenden. Beide sollten Löschvorgänge haben.

Grund: Sie sind besorgt über die Größe oder wollen die Kontrolle über die Speicherzuordnung

Lösung:. Verwenden Sie eine Arraylist mit einer bestimmten Anfangsgröße

Ein Arraylist ist einfach ein Array, das sich ausdehnen kann, aber es muss nicht immer so tun. Es wird über das Hinzufügen / Entfernen von Elementen sehr intelligent sein, aber auch hier, wenn Sie einsetzen / LOT aus der Mitte zu entfernen, verwenden Sie einen LinkedList.

Grund: Sie haben ein Array kommen und ein Array wieder - so dass Sie wollen auf einem Array betreiben

Lösung: Konvertieren Sie es zu einem Arraylist, das Element löschen und wandeln sie zurück

Grund: Sie denken, dass Sie besseren Code schreiben können, wenn Sie es selbst tun

Lösung: Sie können nicht, ein Array oder verlinkte Liste verwenden

.

Grund: Dies ist eine Klassenzuordnung und es nicht erlaubt ist, oder Sie haben keinen Zugriff auf die Sammlung apis aus irgendeinem Grund

Voraussetzung: Sie müssen das neue Array die richtige „Größe“ sein

Lösung: Scannen Sie das Array für passende Artikel und sie zählen. Erstellen Sie ein neues Array der richtigen Größe (Originalgröße - Anzahl der Spiele). verwenden System.arraycopy wiederholt jede Gruppe von Elementen Sie kopieren möchten in Ihrem neuen Array behalten. Wenn dies eine Klassenzuordnung ist und Sie können nicht System.arraycopy verwenden, kopieren Sie sie nur einer nach dem anderen mit der Hand in einer Schleife aber nicht immer diese in der Produktion Code tun, weil es viel langsamer. (Diese Lösungen werden in anderen Antworten sowohl detailliert)

Grund: Sie müssen Bare-Metal

laufen

Voraussetzung: Sie müssen nicht unnötig Platz zuzuweisen oder zu lange dauern

Annahme:. Sie sind die Größe des Arrays (Länge) verwendet Tracking getrennt, weil sonst würden Sie Ihre Array für Löschungen / Inserts umverteilen müssen

Ein Beispiel, warum Sie vielleicht, dies zu tun: eine einzige Reihe von Primitiven (Lassen Sie uns int Werte sagen) wird einen wesentlichen Teil Ihrer Widder nehmen - wie 50%! Ein Arraylist würde diese in eine Liste von Zeigern zwingen Objekte ganze Zahl, die ein paar Mal, dass die Menge an Speicher verwenden würde.

Lösung: iterieren Ihr Array und wann immer Sie ein Element finden zu entfernen (nennen wir es Element n), System.arraycopy verwenden Sie den Schwanz des Feldes über die „gelöschten“ Element (Quelle und Ziel sind gleiche Array) zu kopieren --es ist intelligent genug, um die Kopie in der richtigen Richtung zu tun, damit der Speicher selbst nicht überschrieben werden:

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

Sie werden wahrscheinlich als dies sein smarter wollen, wenn Sie zu einem Zeitpunkt mehr als ein Element löschen. Sie würden nur den Bereich zwischen einem „Spiel“ bewegen und die nächsten anstatt dem gesamten Schwanz und wie immer, vermeiden zweimal jeden Brocken bewegen.

In diesem letzten Fall müssen Sie unbedingt die Arbeit selbst zu tun, und mit System.arraycopy ist wirklich der einzige Weg, es zu tun, da es den besten möglicherweise Weg zu wählen, gehen Speicher für Ihre Computer-Architektur zu bewegen - es sollte sein viele Male schneller als jeder Code könnte man vernünftigerweise selbst schreiben.

EDIT:

Der Punkt mit den Nullen in dem Array gelöscht wurde. Sorry für meine Kommentare.

Original:

Ehm ... die Zeile

array = list.toArray(array);

ersetzt alle Lücken in dem Array, in dem das entfernte Element mit war null . Dies könnte gefährlich , da die Elemente entfernt werden, aber die Länge des Arrays bleibt gleich!

Wenn Sie dies vermeiden wollen, verwenden Sie einen neuen Array als Parameter für toArray (). Wenn Sie möchten, don `t removeAll verwenden, wäre ein Set eine Alternative sein:

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

Gibt:

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

Dabei gilt als aktuelle akzeptierte Antwort von Chris Yester Junge Ausgänge:

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

mit dem Code

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

ohne irgendwelche Null-Werte hinter sich gelassen.

Mein kleiner Beitrag zu diesem Problem.

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

}

Initial Array

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

Wenn Sie 51 wollen entfernen, das ist Index 2, Verwendung folgende

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

Es hängt davon ab, was Sie unter „entfernen“? Ein Array ist eine feste Größe Konstrukt - Sie nicht die Anzahl der Elemente in es ändern können. So können Sie entweder a) ohne die Elemente eine neue, kürzere, Array erstellen möchten Sie nicht oder b) weisen Sie die Einträge, die Sie etwas nicht wollen, dass ihre ‚leer‘ Status anzeigt; in der Regel null, wenn Sie nicht mit Primitiven arbeiten.

Im ersten Fall eine Liste aus dem Array erstellen, um die Elemente entfernen, und erstellen Sie aus der Liste ein neues Array. Wenn die Leistung wichtig Iterierte über das Array alle Elemente zuweisen, die nicht zu einer Liste entfernt werden sollen, und dann ein neues Array aus der Liste erstellen. Im zweiten Fall einfach durchlaufen und weisen null auf die Array-Einträge.

Arrgh, kann ich nicht den Code bekommen richtig zu zeigen. Sorry, ich habe es funktioniert. Leider wieder, ich glaube nicht, dass ich die Frage richtig zu lesen.

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

Werden alle Elemente mit Ausnahme des einen mit dem Index kopieren 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 einer Reihe von Strings wie

String name = 'a b c d e a f b d e' // wie String name = 'aa bb c d e aa f bb d e' sein könnte

Ich baue die folgende Klasse

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

dieses Ergebnis zu erzielen

a b c d e f

Hoffnung dieser Code Hilfe jedermann Grüße

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.

Verwendung:

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

Weisen null zu den Array-Standorten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top