Comment supprimer tous les éléments nuls d'un tableau ArrayList ou String?
j'ai essayer avec une boucle comme ça
// ArrayList tourists
for (Tourist t : tourists) {
if (t != null) {
t.setId(idForm);
}
}
mais ce n'est pas gentil. Quelqu'un peut-il me proposer une meilleure solution?
Quelques repères pour faire la meilleure décision:
en boucle Pour boucle et Itérateur Test de Performance
16 réponses
, Essayez:
tourists.removeAll(Collections.singleton(null));
Lire API Java . Le code lancera java.lang.UnsupportedOperationException
pour les listes immuables (telles que créées avec Arrays.asList
); voir cette réponse pour plus de détails.
à partir de 2015, c'est la meilleure façon (Java 8):
tourists.removeIf(Objects::isNull);
Note: ce code lancera java.lang.UnsupportedOperationException
pour les listes de taille fixe (telles que créées avec des tableaux.asList), y compris les listes immuables.
list.removeAll(Collections.singleton(null));
Il Jette UnsupportedException si vous l'utilisez sur les Tableaux.asList parce qu'il vous donne immuable copie donc il ne peut pas être modifié. Voir ci-dessous le code. Il crée Mutable copie et ne lancera aucune exception.
public static String[] clean(final String[] v) {
List<String> list = new ArrayList<String>(Arrays.asList(v));
list.removeAll(Collections.singleton(null));
return list.toArray(new String[list.size()]);
}
si vous préférez les objets de données immuables, ou si vous ne voulez pas être destructeur de la liste d'entrées, vous pouvez utiliser les prédicats de Guava.
ImmutableList.copyOf(Iterables.filter(tourists, Predicates.notNull()))
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
il y a un moyen facile de supprimer toutes les valeurs null
de collection
.Vous devez passer une collection contenant null comme paramètre à removeAll()
méthode
List s1=new ArrayList();
s1.add(null);
yourCollection.removeAll(s1);
la classe Objects
a un nonNull
Predicate
qui peut être utilisé avec filter
.
par exemple:
tourists.stream().filter(Objects::nonNull).collect(Collectors.toList());
en utilisant Java 8, Vous pouvez le faire en utilisant stream()
et filter()
tourists = tourists.stream().filter(t -> t != null).collect(Collectors.toList())
ou
tourists = tourists.stream().filter(Objects::nonNull).collect(Collectors.toList())
pour plus d'informations: Java 8-Streams
C'est un moyen facile de supprimer les valeurs nulles par défaut de arraylist
tourists.removeAll(Arrays.asList(null));
sinon chaîne valeur "null" Supprimer de arraylist
tourists.removeAll(Arrays.asList("null"));
j'ai joué avec ça et j'ai découvert que trimToSize() semble fonctionner. Je travaille sur la plateforme Android donc ça pourrait être différent.
nous pouvons utiliser iterator pour le même pour supprimer toutes les valeurs nulles.
Iterator<Tourist> itr= tourists.iterator();
while(itr.hasNext()){
if(itr.next() == null){
itr.remove();
}
}
j'ai utilisé l'interface stream ainsi que l'opération stream collect et une méthode helper-pour générer une nouvelle liste.
tourists.stream().filter(this::isNotNull).collect(Collectors.toList());
private <T> boolean isNotNull(final T item) {
return item != null;
}
Pré-Java 8, vous devez utiliser:
tourists.removeAll(Collections.singleton(null));
Post-Java 8 use:
tourists.removeIf(Objects::isNull);
la raison en est la complexité temporelle. Le problème avec les tableaux est qu'une opération de suppression peut prendre du temps O(n) pour terminer. En fait, en Java, il s'agit d'une copie de tableau des éléments restants déplacés pour remplacer l'élément vide. De nombreuses autres solutions proposées ici déclencheront ce problème. Le premier est techniquement O(n*m) où m est 1 parce que c'est un singleton est nul: donc O(n)
vous devriez enlever tout le singleton, à l'intérieur il fait un batchRemove() qui a une position de lecture et une position d'écriture. Et parcourt la liste. Quand il frappe un null, il itère simplement la position de lecture par 1. Quand ils sont les mêmes il passe, quand ils sont différents il continue à se déplacer le long de la copie des valeurs. Puis à la fin il ajuste à la taille.
, Il a effectivement fait cela en interne:
public static <E> void removeNulls(ArrayList<E> list) {
int size = list.size();
int read = 0;
int write = 0;
for (; read < size; read++) {
E element = list.get(read);
if (element == null) continue;
if (read != write) list.set(write, element);
write++;
}
if (write != size) {
list.subList(write, size).clear();
}
}
que vous pouvez voir explicitement est une opération O(n).
la seule chose qui pourrait jamais être plus rapide est si vous itériez la liste des deux extrémités, et quand vous trouvez un null, vous définissez sa valeur égale à la valeur que vous avez trouvée à la fin, et décrémentez cette valeur. Et itérée jusqu'à ce que les deux valeurs correspondent. Vous gâcheriez l'ordre, mais réduirait considérablement le nombre de valeurs vous opposez ceux que vous avez laissés seuls. Ce qui est une bonne méthode pour savoir mais ne vous aidera pas beaucoup ici que .set() est fondamentalement libre, mais que le formulaire de suppression est un outil utile pour votre ceinture.
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
bien que cela semble assez raisonnable, l' .supprimer () sur l'itérateur appels internes:
ArrayList.this.remove(lastRet);
qui est de nouveau l'opération O(n) dans le remove. Il ne fait pas de Système.arraycopy() qui n'est encore pas ce que vous voulez, si vous vous souciez de la vitesse. Cela fait n^2.
il y a aussi:
while(tourists.remove(null));
qui est O (M*N^2). Ici, nous ne nous contentons pas de répéter la liste. Nous réitérons la liste entière, chaque fois que nous correspondons à la nulle. Ensuite nous effectuons des opérations n/2 (moyennes) pour faire le système.arraycopy () pour effectuer la suppression. Vous pourriez littéralement, trier la collection entière entre les éléments avec des valeurs et des éléments avec des valeurs nulles et couper la fin en moins de temps. En fait, c'est vrai pour tous les cassés. Au moins en théorie, le système réel.arraycopy n'est pas vraiment un N fonctionnement dans la pratique. En théorie, la théorie et la pratique sont la même chose; en pratique, elles ne le sont pas.
utilisant Java 8 ceci peut être réalisé de différentes façons en utilisant des flux, des flux parallèles et la méthode removeIf
:
List<String> stringList = new ArrayList<>(Arrays.asList(null, "A", "B", null, "C", null));
List<String> listWithoutNulls1 = stringList.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList()); //[A,B,C]
List<String> listWithoutNulls2 = stringList.parallelStream()
.filter(Objects::nonNull)
.collect(Collectors.toList()); //[A,B,C]
stringList.removeIf(Objects::isNull); //[A,B,C]
le flux parallèle utilisera les processeurs disponibles et accélérera le processus pour les listes de taille raisonnable. Il est toujours conseillé de référence avant d'utiliser les ruisseaux.
similaire à @Lithium answer mais ne jette pas de "liste ne peut pas contenir le type nul "erreur:
list.removeAll(Collections.<T>singleton(null));