web-dev-qa-db-fra.com

Supprimer un élément d'un tableau (Java)

Existe-t-il un moyen rapide (et agréable) de supprimer un élément d'un tableau en Java?

140
Tobias

Vous pouvez utiliser ArrayUtils de commons lang.

array = ArrayUtils.removeElement(array, element)

bibliothèque commons.Apache.org: Javadocs

231
Peter Lawrey

Votre question n'est pas très claire. De votre propre réponse, je peux mieux dire ce que vous essayez de faire:

public static String[] removeElements(String[] input, String deleteMe) {
    List result = new LinkedList();

    for(String item : input)
        if(!deleteMe.equals(item))
            result.add(item);

    return result.toArray(input);
}

NB: Ceci n'est pas testé. La vérification des erreurs est laissée comme un exercice au lecteur (je lirais IllegalArgumentException si une entrée ou deleteMe est nul; une liste vide sur une entrée de liste nulle n'a pas de sens. Supprimer des chaînes nulles du tableau pourrait avoir un sens, mais je Cela restera aussi un exercice; actuellement, il lancera un NPE quand il essaiera d’appeler égal à deleteMe si deleteMe est nul.)

Les choix que j'ai faits ici:

J'ai utilisé une LinkedList. L'itération doit être aussi rapide et vous évitez les redimensionnements ou l'attribution d'une liste trop longue si vous supprimez de nombreux éléments. Vous pouvez utiliser une liste de tableaux et définir la taille initiale en fonction de la longueur de l'entrée. Cela ne ferait probablement pas beaucoup de différence.

47
Adam Jaskiewicz

Le meilleur choix serait d'utiliser une collection, mais si pour une raison quelconque, utilisez arraycopy . Vous pouvez l'utiliser pour copier depuis et vers le même tableau avec un décalage légèrement différent.

Par exemple:

public void removeElement(Object[] arr, int removedIdx) {
    System.arraycopy(arr, removedIdx + 1, arr, removedIdx, arr.length - 1 - removedIdx);
}

Modifier en réponse au commentaire:

Ce n'est pas un autre bon moyen, c'est vraiment le seul moyen acceptable: tous les outils qui permettent cette fonctionnalité (comme Java.ArrayList ou les utilitaires Apache) utiliseront cette méthode sous la couverture. En outre, vous devriez VRAIMENT utiliser ArrayList (ou une liste chaînée si vous en supprimez beaucoup), donc cela ne devrait même pas être un problème, à moins que vous ne le fassiez comme devoir.

Pour allouer une collection (crée un nouveau tableau), supprimez un élément (ce que la collection utilisera avec arraycopy), puis appelez toArray dessus (crée un SECOND nouveau tableau) car chaque suppression nous amène au point où ce n'est pas un problème d'optimisation. , c’est une mauvaise programmation criminelle.

Supposons que vous ayez un tableau prenant, disons, 100 Mo de RAM. Maintenant, vous voulez itérer dessus et supprimer 20 éléments.

Essaie...

Je sais que vous présumez que cela ne va pas être si important, ou que si vous en supprimiez autant à la fois, vous le coderiez différemment, mais j'ai corrigé énormément de code où quelqu'un a fait de telles suppositions.

42
Bill K

Vous ne pouvez pas supprimer un élément du tableau de base Java. Jetez un coup d'œil à diverses Collections et ArrayList à la place.

37
Vlad Gudim

Une bonne solution serait d'utiliser une liste au lieu d'un tableau.

List.remove(index)

Si vous avez pour utiliser des tableaux, deux appels à System.arraycopy seront probablement les plus rapides.

Foo[] result = new Foo[source.length - 1];
System.arraycopy(source, 0, result, 0, index);
if (source.length != index) {
    System.arraycopy(source, index + 1, result, index, source.length - index - 1);
}

(Arrays.asList est également un bon candidat pour travailler avec des tableaux, mais il ne semble pas prendre en charge remove.)

14
jelovirt

Je pense que la question demandait une solution sans l'utilisation de l'API Collections. On utilise les tableaux soit pour les détails de bas niveau, où les performances importent, soit pour une intégration SOA faiblement couplée. Dans ce dernier cas, vous pouvez les convertir en collections et les transmettre à la logique métier.

En ce qui concerne les performances de bas niveau, elles sont généralement déjà obscurcies par l'impératif rapide de mélanger les boucles, etc. Dans ce cas, la conversion en aller-retour entre les collections et les tableaux est fastidieuse, illisible et même gourmande en ressources.

Au fait, TopCoder, ça vous tente? Toujours ces paramètres de tableau! Soyez donc prêt à pouvoir les gérer quand vous êtes dans l’arène.

Ci-dessous, mon interprétation du problème et une solution. La fonctionnalité est différente de celle donnée par Bill K et jelovirt. En outre, il gère correctement le cas où l'élément n'est pas dans le tableau.

J'espère que ça t'as aidé!

public char[] remove(char[] symbols, char c)
{
    for (int i = 0; i < symbols.length; i++)
    {
        if (symbols[i] == c)
        {
            char[] copy = new char[symbols.length-1];
            System.arraycopy(symbols, 0, copy, 0, i);
            System.arraycopy(symbols, i+1, copy, i, symbols.length-i-1);
            return copy;
        }
    }
    return symbols;
}
10
Daniel Dinnyes

Vous pouvez utiliser le API ArrayUtils pour le supprimer "dans un style agréable". Il implémente de nombreuses opérations (supprimer, rechercher, ajouter, contient, etc.) sur des tableaux.
Regarde. Cela m'a simplifié la vie.

4
Tom

Vous ne pouvez pas modifier la longueur d'un tableau, mais vous pouvez modifier les valeurs détenues par l'index en copiant les nouvelles valeurs et en les stockant dans un numéro d'index existant. 1 = micro, 2 = jeff // 10 = george 11 passe à 1 micro remplaçant.

Object[] array = new Object[10];
int count = -1;

public void myFunction(String string) {
    count++;
    if(count == array.length) { 
        count = 0;  // overwrite first
    }
    array[count] = string;    
}
2
Andre

Certaines conditions préalables sont nécessaires pour celles écrites par Bill K et dadinn

Object[] newArray = new Object[src.length - 1];
if (i > 0){
    System.arraycopy(src, 0, newArray, 0, i);
}

if (newArray.length > i){
    System.arraycopy(src, i + 1, newArray, i, newArray.length - i);
}

return newArray;
2
Binoy Joseph

d'accord, merci beaucoup maintenant j'utilise qc comme ceci:

public static String[] removeElements(String[] input, String deleteMe) {
    if (input != null) {
        List<String> list = new ArrayList<String>(Arrays.asList(input));
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).equals(deleteMe)) {
                list.remove(i);
            }
        }
        return list.toArray(new String[0]);
    } else {
        return new String[0];
    }
}
1
Tobias

J'espère que vous utiliserez les collections Java collection/Java commons!

Avec une Java.util.ArrayList, vous pouvez effectuer les tâches suivantes:

yourArrayList.remove(someObject);

yourArrayList.add(someObject);
0
Martin K.

Copier votre tableau d'origine dans un autre tableau, sans l'élément à supprimer.

Pour ce faire, utilisez une méthode List, Set ... et la méthode remove ().

0
Romain Linsolas

Echangez l'élément à supprimer avec le dernier élément, si redimensionner le tableau n'est pas un intérêt.

0
palindrom