Say I have a List
and I know that I never want to add null
to it. If I am adding null to it, it means I\'m making a mistake. So every time I would
AFAIK, there is no standard implementation available in the JDK. However, the Collection spec says that NullPointerException should be thrown when a collection does not support nulls. you can use the following wrapper to add the functionality to any Collection (you'll have to implement the other Collection methods to delegate them to the wrapped instance):
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);
}
...
}
Although this problem sort of yells "delegate", it's much easier with subclassing since you intend to inherit almost all the same functionality.
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);
}
}
Use Apache Commons Collection:
ListUtils.predicatedList(new ArrayList(), PredicateUtils.notNullPredicate());
Adding null to this list throws IllegalArgumentException
. Furthermore you can back it by any List implementation you like and if necessary you can add more Predicates to be checked.
Same exists for Collections in general.
Use Google Guava:
Constraints.constrainedList(new ArrayList(), Constraints.notNull())
Adding null to this list throws NullPointerException
.
try Collections.checkedList().
Watch out -- several answers here are claiming to solve your problem by wrapping a list and checking in add
and addAll
, but they're forgetting you can also add to a List
via its listIterator
. It's challenging to get a constrained list right, which is why Guava has Constraints.constrainedList
to do it for you.
But before looking at that, first consider whether you only need an immutable list, in which case Guava's ImmutableList
will do that null checking for you anyway. And in the off chance that you can use one of the JDK's Queue
implementations instead, that'll do it too.
(Good list of null-hostile collections: https://github.com/google/guava/wiki/LivingWithNullHostileCollections)
This should work
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);
}
however a bug in the addAll implementation means you need to use the following
List<String> list = Collections.checkedList(
Collections.checkedList(new ArrayList<String>(), String.class), String.class);
and you get
list.add(null); threw java.lang.NullPointerException
list.addAll("", null); threw java.lang.NullPointerException