web-dev-qa-db-fra.com

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 résoudre ce problème?

30
Jeffrey

Triez les index 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 index que vous souhaitez supprimer ultérieurement.

La manière dont vous les triez dépend de la collection que vous utilisez pour stocker les index. Si c'est une liste, vous pouvez faire ceci:

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 je n'ai pas trouvé. Au lieu de ce qui précède, vous pouvez utiliser 

Collections.sort(indices, Collections.reverseOrder());
26
Mark Peters

Pour supprimer des éléments à indexes:

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

Ou, en utilisant l'API Stream de Java 8:

indexes.sort(Comparator.reverseOrder());
indexes.stream().mapToInt(i -> i).forEach(l::remove);
38
aioobe

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
Aviel Gross

Vous pouvez supprimer les éléments en commençant par le plus grand index ou, si vous avez des références aux objets que vous souhaitez supprimer, vous pouvez utiliser la méthode removeAll .

3
Mansoor Siddiqui

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

3
Robby Pond

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
MrJacqes

Si vous avez vraiment beaucoup d'éléments à supprimer (et une longue liste), il peut être plus rapide de parcourir la liste et d'ajouter tous les éléments qui ne doivent pas être supprimés à une nouvelle liste, puisque chaque remove()- step dans une liste de tableaux est copié. tous les éléments après le supprimer un par un. Dans ce cas, si votre 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 hachage, un bitSet ou une structure similaire O (1) -access-pour le contrôle 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
Paŭlo Ebermann

Utilisez goyave ! La méthode que vous recherchez est Iterators.removeAll (Iterator removeFrom, Collection elementsToRemove)

0
nanda

vous souhaiterez peut-être utiliser la méthode subList avec la plage d'index que vous souhaitez supprimer, puis appelez clear ().

(notez 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: pouletcat

0
Gal Rom

Vous pouvez trier les index 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
oyo

En supposant que votre tableau indexes soit trié (par exemple: 1, 3, 19, 29), vous pouvez le faire:

for (int i = 0; i < indexes.size(); i++){
   originalArray.remove(indexes.get(i) - i);
}
0
dor506

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 index à supprimer vous-même, vous pouvez envisager d'utiliser this :

indices.add(0, i);

Cela éliminera le besoin (coûteux) de trier de la liste avant son itération, tout en supprimant des éléments de la liste principale ArrayList.

0
dakshtalwar

commandez votre liste d'index, comme ceci

si 2,12,9,7,3 ordre descend à 12,9,7,3,2

et ensuite faire ceci

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

cela devrait résoudre votre problème.

0
Senad Meškin

Une méthode plus efficace que je n'ai pas vue plus haut consiste à créer un nouvel arraylist et à sélectionner les indices qui survivent en les copiant dans le nouveau tableau. Et enfin réaffecter la référence.

0
carles

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

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

Edit: Je réalise maintenant que ce n’était pas une question de performance mais de logique.

0
ILMTitan

Si vous souhaitez supprimer les positions X à la taille

//a is the ArrayList
a=(ArrayList)a.sublist(0,X-1);
0
Esneyder