Supprimer plusieurs éléments de ArrayList

J'ai un tas d'index et je veux supprimer des éléments à ces index d'un ArrayList. Je ne peux pas faire une simple séquence de remove() s car les éléments sont décalés après chaque suppression. Comment puis-je résoudre ce problème?

30
demandé sur Jeffrey 2011-02-10 00:27:32

16 réponses

Triez les indices par ordre décroissant, puis supprimez-les un par un. Si vous faites cela, il n'y a aucun moyen qu'une suppression affecte les indices que vous souhaitez supprimer plus tard.

Comment vous les trier dépendra de la collection que vous utilisez pour stocker les indices. Si c'est une liste, vous pouvez le faire:

List<Integer> indices;
Collections.sort(indices, new Comparator<Integer>() {
   public int compare(Integer a, Integer b) {
      //todo: handle null
      return b.compareTo(a);
   }
}

Modifier

@aioobe a trouvé l'assistant que j'ai échoué à trouver. Au lieu de ce qui précède, vous pouvez utiliser

Collections.sort(indices, Collections.reverseOrder());
25
répondu Mark Peters 2011-02-09 22:57:34

Pour supprimer des éléments à indexes:

Collections.sort(indexes, Collections.reverseOrder());
for (int i : indexes)
    strs.remove(i);

Ou, en utilisant L'API de flux de Java 8:

indexes.sort(Comparator.reverseOrder());
indexes.stream().mapToInt(i -> i).forEach(l::remove);
38
répondu aioobe 2016-12-15 09:01:11

Vous pouvez supprimer les éléments à partir du plus grand index vers le bas, ou si vous avez des références aux objets que vous souhaitez supprimer, vous pouvez utiliser la méthoderemoveAll .

3
répondu Mansoor Siddiqui 2011-02-09 21:31:06

Vous pouvez supprimer les index dans l'ordre inverse. Si les indices sont dans l'ordre comme 1,2,3 vous pouvez faire removeRange(1, 3).

3
répondu Robby Pond 2011-02-09 21:33:55

Je suis venu ici pour supprimer des éléments dans une plage spécifique (c'est-à-dire tous les éléments entre 2 Index), et j'ai trouvé ceci:

list.subList(indexStart, indexEnd).clear()
3
répondu Aviel Gross 2014-11-02 12:38:15

Je pense que nanda était la bonne réponse.

List<T> toRemove = new LinkedList<T>();
for (T t : masterList) {
  if (t.shouldRemove()) {
    toRemove.add(t);
  }
}

masterList.removeAll(toRemove);
2
répondu MrJacqes 2011-02-09 22:31:41

Si vous avez vraiment beaucoup d'éléments à supprimer (et une longue liste), il peut être plus rapide d'itérer sur la liste et d'ajouter tous les éléments qui ne doivent pas être supprimés à une nouvelle liste, puisque chaque remove()-étape dans une liste de tableau copie tous les éléments après le supprimé un par un. Dans ce cas, si la liste d'index n'est pas déjà triée (et que vous pouvez la parcourir parallèlement à la liste principale), vous pouvez utiliser un HashSet ou un BitSet ou une structure O(1)-access similaire pour la vérification contains():

/**
 * creates a new List containing all elements of {@code original},
 * apart from those with an index in {@code indices}.
 * Neither the original list nor the indices collection is changed.
 * @return a new list containing only the remaining elements.
 */
public <X> List<X> removeElements(List<X> original, Collection<Integer> indices) {
    // wrap for faster access.
    indices = new HashSet<Integer>(indices);
    List<X> output = new ArrayList<X>();
    int len = original.size();
    for(int i = 0; i < len; i++) {
       if(!indices.contains(i)) {
           output.add(original.get(i));
       }
    }
    return output;
}
1
répondu Paŭlo Ebermann 2011-02-09 22:44:21

Commandez votre liste d'index, comme ceci

Si 2,12,9,7,3 ordre desc à 12,9,7,3,2

Et puis faites ceci

for(var i = 0; i < indexes.length; i++) { source_array.remove(indexes[0]); }

Cela devrait résoudre votre problème.

0
répondu Senad Meškin 2011-02-09 21:31:44

, Si les éléments que vous souhaitez supprimer sont tous regroupés, vous pouvez faire un subList(start, end).clear() opération.

Si les éléments que vous souhaitez supprimer sont dispersés, il peut être préférable de créer une nouvelle ArrayList, ajouter uniquement les éléments que vous souhaitez inclure, puis recopier dans la liste d'origine.

Edit: je me rends compte maintenant que ce n'était pas une question de performance mais de logique.

0
répondu ILMTitan 2011-02-09 21:34:16

Vous pouvez trier les indices comme beaucoup l'ont dit, ou vous pouvez utiliser un itérateur et appeler remove ()

List<String> list = new ArrayList<String>();
    list.add("0");
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    list.add("5");
    list.add("6");
    List<Integer> indexes = new ArrayList<Integer>();
    indexes.add(2);
    indexes.add(5);
    indexes.add(3);
    int cpt = 0;
    Iterator<String> it = list.iterator(); 
    while(it.hasNext()){
        it.next();
        if(indexes.contains(cpt)){
            it.remove();
        }
        cpt++;
    }

Cela dépend de ce dont vous avez besoin, mais le tri sera plus rapide dans la plupart des cas

0
répondu oyo 2011-02-09 21:45:43

Utiliser goyave! La méthode que vous recherchez est itérateurs.removeAll(Itérateur removeFrom, Collection elementsToRemove)

0
répondu nanda 2011-02-09 22:01:47

Vous pouvez utiliser la méthode de sous-liste avec la plage d'index que vous souhaitez supprimer et ensuite, appelez clear () dessus.

(Faites attention que le dernier paramètre est exclu et que seuls les premier et deuxième éléments seront supprimés):

public static void main(String[] args) {
    // TODO Auto-generated method stub
    ArrayList<String> animals = new ArrayList<String>();
    animals.add("cow");
    animals.add("dog");
    animals.add("chicken");
    animals.add("cat");
    animals.subList(0, 2).clear();
    for(String s:animals)
        System.out.println(s);
}

}

Le résultat sera: poulet chat

0
répondu Gal Rom 2014-02-10 21:10:10

Si vous voulez supprimer les positions X à la taille

//a is the ArrayList
a=(ArrayList)a.sublist(0,X-1);
0
répondu Esneyder 2015-04-09 23:08:28

En Supposant que votre indexes tableau est trié (par exemple: 1, 3, 19, 29), vous pouvez faire ceci:

for (int i = 0; i < indexes.size(); i++){
   originalArray.remove(indexes.get(i) - i);
}
0
répondu dor506 2016-03-06 18:20:00

Une méthode plus efficace que je suppose que je n'ai pas Vue ci-dessus crée une nouvelle Arraylist et sélectionne les indices qui survivent en les copiant dans le nouveau tableau. Et enfin réaffecter la référence.

0
répondu carles 2016-11-14 03:46:03

Je me suis retrouvé ici pour une requête similaire et la réponse de @aioobe m'a aidé à trouver la solution. Cependant, si vous remplissez la liste des indices à supprimer vous-même, vous pouvez envisager d'utiliser this :

indices.add(0, i);

Cela éliminera le besoin de (le coûteux) tri inverse de la liste avant d'itérer dessus, tout en supprimant des éléments de L'ArrayList principale.

0
répondu dakshtalwar 2016-11-18 22:12:45