Question

Étant donné un tableau d'objets n , supposons qu'il s'agisse d'un tableau de chaînes , doté des valeurs suivantes:

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

Que dois-je faire pour supprimer / supprimer toutes les chaînes / objets égaux à "a" dans le tableau?

Était-ce utile?

La solution

[Si vous voulez du code prêt à l’emploi, faites défiler jusqu’à "Mon édition" " Edit3 " (après la coupe). Le reste est là pour la postérité.]

Pour étoffer L'idée de Dustman :

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

Modifier: J'utilise maintenant Arrays.asList au lieu de Collections.singleton : le singleton est limité à une entrée, alors que le asList Cette approche vous permet d’ajouter d’autres chaînes à filtrer ultérieurement: Arrays.asList ("a", "b", "c") .

Edit2: L'approche ci-dessus conserve le même tableau (le tableau a donc toujours la même longueur); l'élément après le dernier est défini sur null. Si vous voulez un nouveau tableau dimensionné exactement comme vous le souhaitez, utilisez ceci à la place:

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

Éditer3: Si vous utilisez fréquemment ce code dans la même classe, vous pouvez envisager de l'ajouter à votre classe:

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

La fonction devient alors:

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

Ceci arrêtera alors de surcharger votre tas avec des tableaux de chaînes vides inutiles qui seraient autrement new édités chaque fois que votre fonction est appelée.

La suggestion de Cynicalman (voir les commentaires) contribuera également à la gestion des déchets, et par souci d'équité, je devrais le mentionner:

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

Je préfère mon approche, car il peut être plus facile d'obtenir une taille explicite erronée (par exemple, appeler size () sur la mauvaise liste).

Autres conseils

Une alternative à Java 8:

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

Créez un élément List dans le tableau avec Arrays.asList () , puis appelez remove () sur tous les éléments appropriés. Ensuite, appelez toArray () dans la "Liste" pour revenir dans un tableau.

Pas très performant, mais si vous l’encapsulez correctement, vous pourrez toujours faire quelque chose de plus vite plus tard.

Vous pouvez toujours faire:

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

Vous pouvez utiliser une bibliothèque externe:

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

C’est dans le projet Apache Commons Lang http://commons.apache.org/lang/

Voir le code ci-dessous

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

Si vous devez supprimer plusieurs éléments d'un tableau sans le convertir en List ni créer un tableau supplémentaire, vous pouvez le faire en O (n), sans dépendre du nombre d'éléments à supprimer.

Ici, a est un tableau initial, int ... r sont des index (positions) ordonnés distincts d'éléments à supprimer:

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

Petits tests:

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]

Dans votre tâche, vous pouvez d'abord analyser un tableau pour collecter les positions de "a", puis appeler removeItems () .

Quelque chose à propos de la liste puis de la supprimer puis de revenir à un tableau me semble erroné. Je n'ai pas testé, mais je pense que ce qui suit fonctionnera mieux. Oui, je suis probablement en train de pré-optimiser indûment.

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

Je réalise que c'est un très vieux billet, mais certaines des réponses ici m'ont aidé, alors voici la valeur de ma tuppence 'ha'penny!

J'ai eu du mal à faire en sorte que cela fonctionne pendant un bon bout de temps avant de penser que le tableau dans lequel je suis en train d'écrire devait être redimensionné, à moins que les modifications apportées à ArrayList ne laissent pas la taille de la liste. .

Si le ArrayList que vous modifiez se termine avec un nombre d'éléments supérieur ou inférieur au nombre indiqué, la ligne List.toArray () provoquera une exception. vous avez besoin de quelque chose comme List.toArray (new String [] {}) ou List.toArray (new String [0]) afin de créer un tableau avec le nouveau ( correcte) taille.

Cela semble évident maintenant que je le sais. Ce n’est pas si évident pour un débutant sous Android / Java qui s’intéresse à des constructions de code nouvelles et inconnues et qui n’est pas évident dans certains des articles précédents, alors je voulais simplement que ce point soit vraiment clair pour quiconque se gratter la tête pendant des heures comme j’étais !

Il y a beaucoup de réponses ici. Le problème, à ce que je vois, c’est que vous n’avez pas dit POURQUOI vous utilisez un tableau plutôt qu’une collection. Laissez-moi donc vous suggérer quelques raisons et les solutions qui s’appliqueraient. des solutions ont déjà été répondues dans d'autres questions ici, donc je ne vais pas entrer dans trop de détails):

raison: vous ne saviez pas que le package de collecte existait ou ne le faisait pas confiance

solution: Utilisez une collection.

Si vous envisagez d’ajouter ou de supprimer du milieu, utilisez une LinkedList. Si vous êtes vraiment préoccupé par la taille ou indexez souvent au milieu de la collection, utilisez un ArrayList. Ces deux opérations devraient comporter des opérations de suppression.

raison: votre taille vous préoccupe ou vous souhaitez contrôler l'allocation de mémoire

solution: utilisez une liste de tableaux avec une taille initiale spécifique.

Une ArrayList est simplement un tableau qui peut s’agrandir, mais il n’est pas toujours nécessaire de le faire. Ce sera très intelligent d'ajouter / supprimer des éléments, mais encore une fois, si vous insérez / supprimez un LOT du milieu, utilisez une liste liée.

raison: vous avez un tableau entrant et un tableau sortant - vous souhaitez donc opérer sur un tableau

solution: convertissez-le en une liste de tableaux, supprimez l'élément et reconvertissez-le

raison: vous pensez pouvoir écrire un meilleur code si vous le faites vous-même

solution: vous ne pouvez pas utiliser un tableau ou une liste chaînée.

raison: il s'agit d'une tâche de classe et vous n'êtes pas autorisé ou vous n'avez pas accès au système de collecte pour une raison quelconque

hypothèse: le nouveau tableau doit avoir la "taille" correcte

solution: Analysez le tableau pour rechercher les éléments correspondants et comptez-les. Créez un nouveau tableau de la taille correcte (taille d'origine - nombre de correspondances). utilisez plusieurs fois System.arraycopy pour copier chaque groupe d'éléments que vous souhaitez conserver dans votre nouveau groupe. S'il s'agit d'une affectation de classe et que vous ne pouvez pas utiliser System.arraycopy, copiez-les une à la fois à la main dans une boucle, mais ne le faites jamais dans le code de production car il est beaucoup plus lent. (Ces solutions sont détaillées dans d'autres réponses)

raison: vous devez utiliser du métal nu

hypothèse: vous ne devez PAS allouer d’espace inutilement ni prendre trop de temps

hypothèse: vous suivez la taille utilisée dans le tableau (longueur) séparément car sinon, vous devrez réaffecter votre tableau aux suppressions / insertions.

Voici un exemple de raison pour laquelle vous voudrez peut-être faire cela: un seul tableau de primitives (disons des valeurs int) prend une part importante de votre bélier - comme 50%! Un ArrayList les forcerait dans une liste de pointeurs sur des objets Integer qui utiliseraient quelques fois cette quantité de mémoire.

solution: parcourez votre tableau et chaque fois que vous trouvez un élément à supprimer (appelons-le élément n), utilisez System.arraycopy pour copier la queue du tableau sur le caractère "supprimé". element (la source et la destination sont identiques) - il est assez intelligent pour faire la copie dans le bon sens pour que la mémoire ne s’écrase pas:

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

Vous voudrez probablement être plus intelligent que cela si vous supprimez plusieurs éléments à la fois. Vous ne déplaceriez la zone qu'entre un match et " et la suivante plutôt que toute la queue et comme toujours, évitez de déplacer deux fois un morceau.

Dans ce dernier cas, vous devez absolument faire le travail vous-même, et utiliser System.arraycopy est vraiment le seul moyen de le faire, car il va choisir le meilleur moyen de déplacer éventuellement de la mémoire pour l'architecture de votre ordinateur. plusieurs fois plus rapidement que n'importe quel code que vous pourriez raisonnablement écrire vous-même.

EDIT:

Le point avec les valeurs NULL dans le tableau a été effacé. Désolé pour mes commentaires.

Original:

Euh ... la ligne

array = list.toArray(array);

remplace tous les espaces du tableau contenant l'élément null . Cela peut être dangereux , car les éléments sont supprimés, mais la longueur du tableau reste la même!

Si vous voulez éviter cela, utilisez un nouveau tableau comme paramètre pour toArray (). Si vous ne voulez pas utiliser removeAll, un ensemble serait une alternative:

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

donne:

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

Où, comme réponse actuelle acceptée par Chris Yester Young:

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

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

sans laisser de valeur NULL.

Ma petite contribution à ce problème.

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

}

Tableau initial

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

si vous souhaitez supprimer 51 qui est l'index 2, utilisez la commande suivante

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

Cela dépend de ce que vous entendez par "supprimer". Un tableau est une construction de taille fixe - vous ne pouvez pas changer le nombre d'éléments qu'il contient. Vous pouvez donc soit a) créer un nouveau tableau plus court sans les éléments que vous ne voulez pas, soit b) affecter les entrées que vous ne voulez pas à quelque chose qui indique leur statut «vide»; généralement nul si vous ne travaillez pas avec des primitives.

Dans le premier cas, créez une liste à partir du tableau, supprimez les éléments et créez un nouveau tableau dans la liste. Si les performances sont importantes, effectuez une itération sur le tableau en affectant les éléments qui ne doivent pas être supprimés à une liste, puis créez un nouveau tableau à partir de la liste. Dans le second cas, il suffit de passer et d’attribuer la valeur null aux entrées du tableau.

Arrgh, je ne parviens pas à afficher correctement le code. Désolé, ça marche. Désolé encore, je ne pense pas avoir bien lu la question.

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

Copiera tous les éléments sauf celui d'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) );
            }

Dans un tableau de chaînes tel que

String name = 'a b c d e a f b d e' // pourrait ressembler à String name = 'aa bb c d e aa f bb d e'

Je construis la classe suivante

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

obtenir ce résultat

a b c d e f

espérons que ce code aide quelqu'un Cordialement

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.

Utiliser:

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

Attribuez la valeur null aux emplacements du tableau.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top