Comment supprimer des objects d’un tableau en Java?

Étant donné un tableau de n objects, supposons qu’il s’agisse d’un tableau de chaînes , et qu’il possède les 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 / objects égaux à “a” dans le tableau?

[Si vous souhaitez un code prêt à l’emploi, accédez à mon “Edit3” (après la coupure). Le rest est ici pour la postérité.]

Pour étoffer l’idée de Dustman :

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

Edit: J’utilise maintenant Arrays.asList au lieu de Collections.singleton : singleton est limité à une entrée, alors que l’approche asList vous permet d’append d’autres chaînes pour filtrer plus tard: 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 requirejs, utilisez plutôt ceci:

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

Edit3: Si vous utilisez ce code fréquemment dans la même classe, vous pouvez envisager d’append ceci à votre classe:

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

La fonction devient alors:

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

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

La suggestion de cynicalman (voir les commentaires) aidera également à éliminer les déchets, et pour être juste, je devrais le mentionner:

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

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

Une alternative à Java 8:

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

Faites une List du tableau avec Arrays.asList() et appelez remove() sur tous les éléments appropriés. Ensuite, appelez toArray() sur 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 rapide par la suite.

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 a = new ArrayList<>(Arrays.asList(strings)); a.remove(i); strings = new String[a.size()]; a.toArray(strings); 

Si vous devez supprimer plusieurs éléments du tableau sans les convertir en List ni en créer de nouveaux, vous pouvez le faire dans O (n) sans dépendre du nombre d’éléments à supprimer.

Ici, a est le tableau initial, int... r sont des indices séparés (positions) des é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:

 Ssortingng[] 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 parsingr le tableau pour collecter les positions de "a", puis appeler removeItems() .

Quelque chose à propos de la faire une liste, puis la retirer puis revenir à un tableau me semble erroné. Je n’ai pas testé, mais je pense que les performances suivantes seront meilleures. Oui, je suis probablement pré-optimisé indûment.

 boolean [] deleteItem = new boolean[arr.length]; int size=0; for(int i=0;i 

Je me rends compte que c’est un très vieux post, mais certaines des réponses ici m’ont aidé, alors voici la valeur de votre tuppence ‘ha’penny!

J’ai eu du mal à le faire fonctionner pendant un bon moment avant de passer au crible que le tableau dans lequel j’écrivais devait être redimensionné, à moins que les modifications apscopes à ArrayList laissent la taille de la liste inchangée.

Si la liste de ArrayList que vous modifiez se termine par un nombre d’éléments plus ou moins important, la ligne List.toArray() provoquera une exception. Vous aurez donc besoin de quelque chose comme List.toArray(new Ssortingng[] {}) ou List.toArray(new Ssortingng[0]) afin de créer un tableau avec la nouvelle taille (correcte).

Cela semble évident maintenant que je le sais. Pas si évident pour un débutant Android / Java qui se familiarise avec des constructions de code nouvelles et inconnues et qui ne sont pas évidentes dans certains articles précédents, alors je voulais juste que ce point soit clair pour quiconque se grattait la tête pendant des heures. !

MODIFIER:

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

Original:

Ehm … la ligne

 array = list.toArray(array); 

remplace toutes les lacunes dans le tableau où l’élément supprimé a été avec null . Cela peut être dangereux , car les éléments sont supprimés, mais la longueur du tableau rest la même!

Si vous souhaitez éviter cela, utilisez un nouveau tableau en tant que paramètre pour toArray (). Si vous ne voulez pas utiliser removeAll, un Set serait une alternative:

  Ssortingng[] array = new Ssortingng[] { "a", "bc" ,"dc" ,"a", "ef" }; System.out.println(Arrays.toSsortingng(array)); Set asSet = new HashSet(Arrays.asList(array)); asSet.remove("a"); array = asSet.toArray(new Ssortingng[] {}); System.out.println(Arrays.toSsortingng(array)); 

Donne:

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

Où en tant que la réponse acceptée actuelle de Chris Yester Young produit:

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

avec le code

  Ssortingng[] array = new Ssortingng[] { "a", "bc" ,"dc" ,"a", "ef" }; System.out.println(Arrays.toSsortingng(array)); List list = new ArrayList(Arrays.asList(array)); list.removeAll(Arrays.asList("a")); array = list.toArray(array); System.out.println(Arrays.toSsortingng(array)); 

sans aucune valeur nulle laissée.

Ma petite consortingbution à ce problème.

 public class DeleteElementFromArray { public static Ssortingng foo[] = {"a","cc","a","dd"}; public static Ssortingng search = "a"; public static void main(Ssortingng[] 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
		      	

Il y a beaucoup de réponses ici – le problème que je vois est que vous n’avez pas dit POURQUOI vous utilisez un tableau au lieu d’une collection, laissez-moi vous suggérer quelques raisons et quelles solutions s’appliqueraient (la plupart des solutions ont déjà reçu des réponses à d’autres questions ici, alors je n’entrerai pas trop dans les détails):

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

solution: Utilisez une collection.

Si vous prévoyez d’append / supprimer du milieu, utilisez une LinkedList. Si vous êtes vraiment préoccupé par la taille ou l’index souvent au milieu de la collection, utilisez une ArrayList. Les deux doivent avoir des opérations de suppression.

raison: vous êtes préoccupé par la taille ou souhaitez contrôler l’allocation de mémoire

solution: Utilisez une ArrayList avec une taille initiale spécifique.

Un ArrayList est simplement un tableau qui peut se développer, mais il n’a pas toujours besoin de le faire. Il sera très judicieux d’append / de supprimer des éléments, mais encore une fois, si vous insérez / supprimez un LOT du milieu, utilisez une LinkedList.

raison: vous avez un tableau entrant et un tableau sortant – vous voulez donc opérer sur un tableau

solution: Convertissez-le en ArrayList, 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 une liste Array ou Linked.

raison: ceci est une affectation de classe et vous n’êtes pas autorisé ou vous n’avez pas access à la collection apis pour une raison quelconque

hypothèse: vous avez besoin que le nouveau tableau soit la “taille” correcte

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

raison: vous devez exécuter du métal nu

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

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

Un exemple de la raison pour laquelle vous pourriez vouloir faire ceci: un tableau unique de primitives (disons des valeurs int) prend une partie importante de votre RAM – comme 50%! Un ArrayList les forcerait dans une liste de pointeurs vers des objects Integer qui utiliseraient quelques fois cette quantité de mémoire.

solution: Itérer sur 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 l’élément “supprimé” (Source et Destination ont le même tableau) – it est assez intelligent pour faire la copie dans la bonne direction afin que la mémoire ne se remplace pas:

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

Vous voudrez probablement être plus intelligent que cela si vous supprimez plus d’un élément à la fois. Vous ne feriez que déplacer la zone entre un “match” et le suivant plutôt que la queue entière et, comme toujours, évitez de déplacer un morceau deux fois.

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 la mémoire pour l’architecture de votre ordinateur – il devrait être beaucoup plus rapide que tout code que vous pourriez raisonnablement écrire vous-même.

Cela dépend de ce que vous entendez par “supprimer”? Un tableau est une construction de taille fixe – vous ne pouvez pas modifier 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 ou b) affecter les entrées dont vous ne voulez pas quelque chose qui indique leur statut «vide»; généralement null 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 à partir de la liste. Si les performances sont importantes, effectuez une itération sur le tableau en atsortingbuant des éléments à ne pas supprimer à une liste, puis créez un nouveau tableau à partir de la liste. Dans le second cas, passez simplement en revue et atsortingbuez la valeur null aux entrées du tableau.

Arrgh, je n’arrive pas à faire apparaître le code correctement. Désolé, je l’ai fait fonctionner. Désolé, je ne pense pas avoir lu la question correctement.

 Ssortingng foo[] = {"a","cc","a","dd"}, remove = "a"; boolean gaps[] = new boolean[foo.length]; int newlength = 0; for (int c = 0; c 

Copiera tous les éléments sauf celui avec index 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) ); } 
 class sd { public static void main(Ssortingng[ ] 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. 

Utilisation:

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

Atsortingbuez la valeur null aux emplacements du tableau.