web-dev-qa-db-fra.com

En Java, supprimer des éléments vides d'une liste de chaînes

En Java, j'ai une ArrayList of Strings comme:

[,Hi, ,How,are,you]

Je veux supprimer les éléments nuls et vides, comment le changer afin qu'il ressemble à ceci:

[Hi,How,are,you]
43
Niranjan Kumar
List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How"));
System.out.println(list);
list.removeAll(Arrays.asList("", null));
System.out.println(list);

Sortie:

[, Hi, null, How]
[Hi, How]
76
smas

C'est une réponse très tardive, mais vous pouvez aussi utiliser le Collections.singleton:

List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How"));
list.removeAll(Collections.singleton(null));
list.removeAll(Collections.singleton(""));
37
tokhi

Une autre façon de faire cela maintenant que nous avons les expressions Java 8 lambda.

arrayList.removeIf(item -> item == null || "".equals(item));
12
Andrew Mairose

Vous pouvez utiliser quelques approches:

  1. Parcourez la liste en appelant Iterator.remove() pour les éléments de la liste que vous souhaitez supprimer. C'est le plus simple.

  2. Appelez à plusieurs reprises List.remove(Object). C’est aussi simple, mais le pire des résultats… car vous balayez de manière répétée le liste entière. (Cependant, cela pourrait être une option pour une liste modifiable dont l'itérateur ne supportait pas remove ... pour une raison quelconque.)

  3. Créez une nouvelle liste, parcourez l'ancienne liste en ajoutant des éléments que vous souhaitez conserver dans une nouvelle liste. 

  4. 3. Si vous ne pouvez pas retourner la nouvelle liste, comme 3. ci-dessus, effacez l'ancienne liste et utilisez addAll pour y ajouter les éléments de la nouvelle liste.

Le choix le plus rapide dépend de la classe de la liste d'origine, de sa taille et du nombre d'éléments à supprimer. Voici quelques facteurs:

  • Pour une ArrayList, chaque opération remove est O(N), où N est la taille de la liste. Il est coûteux de supprimer plusieurs éléments d'une grande ArrayList à l'aide de la méthode Iterator.remove() (ou de la méthode ArrayList.remove(element)). 

    En revanche, la méthode Iterator.remove pour une LinkedList est O(1).

  • Pour un ArrayList, créer et copier une liste est O(N) et relativement pas cher, surtout si vous pouvez vous assurer que la capacité de la liste de destination est suffisamment grande (mais pas trop grande).

    En revanche, créer et copier sur une LinkedList est également O(N), mais considérablement plus coûteux.

Tout cela s’ajoute à un arbre de décision assez complexe. Si les listes sont petites (disons 10 éléments ou moins), vous pouvez probablement vous en tirer avec l'une des approches ci-dessus. Si les listes peuvent être volumineuses, vous devez peser tous les problèmes dans la liste de la taille de la liste et du nombre de suppressions attendus. (Sinon, vous pourriez vous retrouver avec une performance quadratique.)

4
Stephen C
  • Ce code est compilé et fonctionne correctement.
  • Il n'utilise aucun itérateur, donc plus lisible.
  • la liste est votre collection.
  • le résultat est un formulaire filtré (no null no empty).

public static void listRemove() {
    List<String> list = Arrays.asList("", "Hi", "", "How", "are", "you");
    List<String> result = new ArrayList<String>();

    for (String str : list) {
        if (str != null && !str.isEmpty()) {
            result.add(str);
        }
    }

    System.out.println(result);
}
3
Kerem Baydoğan

Si vous obtenez UnsupportedOperationException en utilisant l'une des réponses ci-dessus et que votre List est créé à partir de Arrays.asList(), c'est parce que vous ne pouvez pas éditer une telle List.

Pour résoudre ce problème, enveloppez la Arrays.asList() dans la new LinkedList<String>():

    List<String> list = new LinkedList<String>(Arrays.asList(split));

La source est de cette réponse .

2
AnT

Va déposer cette petite pépite ici:

Stream.of("", "Hi", null, "How", "are", "you")
  .filter(t -> !Strings.isNullOrEmpty(t))
  .collect(ImmutableList.toImmutableList());

Je souhaite de tout cœur que Java ait une filterNot.

2
Sam Berry

Si vous utilisez Java 8, essayez ceci en utilisant l'expression lambda et org.Apache.commons.lang.StringUtils , cela effacera également les valeurs null et blank de array

public static String[] cleanArray(String[] array) {
    return Arrays.stream(array).filter(x -> !StringUtils.isBlank(x)).toArray(String[]::new);
}

ref - https://stackoverflow.com/a/41935895/9696526

2
The Hunter

À propos du commentaire de Andrew Mairose - Bien que ce soit une bonne solution, je voudrais juste ajouter que cette solution ne fonctionnera pas taille fixe des listes.

Vous pouvez essayer de faire comme si:

Arrays.asList(new String[]{"a", "b", null, "c", "    "})
    .removeIf(item -> item == null || "".equals(item));

Mais vous rencontrerez un UnsupportedOperationException at Java.util.AbstractList.remove (puisque asList renvoie une liste non redimensionnable). 

Une solution différente pourrait être la suivante:

List<String> collect =
    Stream.of(new String[]{"a", "b", "c", null, ""})
        .filter(item -> item != null && !"".equals(item))
        .collect(Collectors.toList());

Ce qui produira une belle liste de chaînes :-)

1
Asaf Blum
   private List cleanInputs(String[] inputArray) {
        List<String> result = new ArrayList<String>(inputArray.length);
        for (String input : inputArray) {
            if (input != null) {
                String str = input.trim();
                if (!str.isEmpty()) {
                    result.add(str);
                }
            }
        }
        return result;
    }
0
user2982704