Disons que j’ai une List
et que je sais que je ne veux jamais y ajouter null
. Si j'ajoute null à cela, cela signifie que je commets une erreur. Donc, chaque fois que j'appellerais autrement list.add(item)
j'appellerais plutôt if (item == null) throw SomeException(); else list.add(item);
. Existe-t-il une classe List
(peut-être dans Apache Commons ou quelque chose d’autre) qui le fait pour moi?
Question similaire: Aide à supprimer les références null dans une liste Java? mais je ne veux pas supprimer toutes les NULL, je veux m'assurer qu'elles ne seront jamais ajoutées en premier lieu.
Faites attention - plusieurs réponses prétendent résoudre votre problème en enveloppant une liste et en enregistrant add
et addAll
, mais elles oublient que vous pouvez également ajouter une List
via sa listIterator
. Il est difficile d'avoir une liste restreinte correcte, c'est pourquoi Guava a Constraints.constrainedList
pour le faire pour vous.
Mais avant de regarder cela, demandez-vous d’abord si vous avez seulement besoin d’une liste immuable /, auquel cas la variable ImmutableList
de Guava effectuera cette vérification nulle pour vous. Et si vous pouvez utiliser l'une des implémentations Queue
du JDK à la place, vous le ferez aussi.
(Bonne liste des collections null-hostiles: https://github.com/google/guava/wiki/LivingWithNullHostileCollections )
Utilisez Apache Commons Collection:
ListUtils.predicatedList(new ArrayList(), PredicateUtils.notNullPredicate());
Ajouter null à cette liste jette IllegalArgumentException
. En outre, vous pouvez l’ajouter à l’implémentation de la liste de votre choix et, si nécessaire, ajouter plus de prédicats à vérifier.
Même chose pour les collections en général.
Utilisez Google Guava:
Constraints.constrainedList(new ArrayList(), Constraints.notNull())
Ajouter null à cette liste jette NullPointerException
.
Autant que je sache, il n’ya pas d’implémentation standard disponible dans le JDK. Cependant, la spécification Collection indique que NullPointerException doit être levé lorsqu'une collection ne prend pas en charge les valeurs NULL. vous pouvez utiliser le wrapper suivant pour ajouter la fonctionnalité à n'importe quelle collection (vous devrez implémenter les autres méthodes de la collection pour les déléguer à l'instance encapsulée):
class NonNullCollection<T> implements Collection<T> {
private Collection<T> wrapped;
public NonNullCollection(Collection<T> wrapped) {
this.wrapped = wrapped;
}
@Override
public void add(T item) {
if (item == null) throw new NullPointerException("The collection does not support null values");
else wrapped.add(item);
}
@Override
public void addAll(Collection<T> items) {
if (items.contains(null)) throw new NullPointerException("The collection does not support null values");
else wrapped.addAll(item);
}
...
}
Vous pouvez le faire en encapsulant simplement une instance d'une liste et en fournissant la méthode add à vérification nulle. En d’autres termes, votre classe n’aurait que deux méthodes et une variable interne.
Si vous avez besoin de toutes les fonctionnalités d’une liste, vous pouvez envisager l’utilisation de Guava (anciennement Google Collections) ForwardingList .
Une autre approche consiste simplement à étendre la liste, mais il faut éviter de remplacer add
et addAll
.
Fait intéressant, la goyave a un standardAddAll , qui peut être utilisé comme implémentation de addAll, ce qui résout au moins une partie du problème.
Bien que ce problème appelle en quelque sorte "délégué", il est beaucoup plus facile de sous-classer car vous avez l'intention d'hériter de la même fonctionnalité.
class MyList extends List {
//Probably need to define the default constructor for the compiler
public add(Object item) {
if (item == null) throw SomeException();
else super.add(item);
}
public addAll(Collection c) {
if (c.contains(null)) throw SomeException();
else super.addAll(c);
}
}
Cela devrait marcher
List<String> list = Collections.checkedList(new ArrayList<String>(), String.class);
try {
list.add(null);
throw new AssertionError("Expected a NPE");
} catch (NullPointerException expected) {
System.out.println("list.add(null); threw "+expected);
}
try {
List<String> list2 = Arrays.asList("", null);
list.addAll(list2);
throw new AssertionError("Expected a NPE");
} catch (NullPointerException expected) {
System.out.println("list.addAll(\"\", null); threw " + expected);
}
cependant, un bogue dans l'implémentation addAll signifie que vous devez utiliser le code suivant.
List<String> list = Collections.checkedList(
Collections.checkedList(new ArrayList<String>(), String.class), String.class);
et vous obtenez
list.add(null); threw Java.lang.NullPointerException
list.addAll("", null); threw Java.lang.NullPointerException