I have List<Long> countriesList which contains Long values which are country ids.
Now I am iterating over some List<UserRequests> list by using streams.
userRequests.stream().
forEach(userRequest->
{
UserData=userRepository.findById(userRequest.getId()); //fine
if (CollectionUtils.isNotEmpty(countriesList) && countriesList.contains(userRequest.getCountryId()))//getting NPE here
{
//do some operation
}
});
I tried to debug by evaluating individual statements.
I have made sure countriesList have some data
First part CollectionUtils.isNotEmpty(countriesList) is returning true.
userRequest is also not null but userRequest.getCountryId() is null.
And when I evaluated countriesList.contains(userRequest.getCountryId()), I am getting Null pointer exception here. why not false ?
I am confused what wrong am I doing.
Is default list.contains(null) behaviour is like that only or is it because I am calling it within stream()?
Just for simplification I have created simple list and compared with null.
class Test {
public static void main(String[] args) {
List<Long> longList = List.of(1L, 2L, 3L);
System.out.println("Comparing long list with null::" + longList.contains(null));
}
}
This is the exception I am getting:
Exception in thread "main" java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:222)
at java.base/java.util.ImmutableCollections$AbstractImmutableList.indexOf(ImmutableCollections.java:166)
at java.base/java.util.ImmutableCollections$AbstractImmutableList.contains(ImmutableCollections.java:197)
at com.test.Test.main(Test.java:26)
But If I do:
List<Long> longList = new ArrayList<>();
longList.add(1L);
System.out.println("Comparing long list with null::" + longList.contains(null));
Why it is printing false? Why no NullPointerException here?
Advertisement
Answer
Why
list.contains(null)throwing null pointer exception?
Because this is what the specs say can happen.
The specific reasoning for the List.of(...) case is as follows:
The
List.ofmethods are specified as producing unmodifiable lists.Unmodifiable lists are specified to not permit
nullelements:“They disallow null elements. Attempts to create them with
nullelements result inNullPointerException.”The javadoc for
List.containsstates:“Throws:
NullPointerException– if the specified element isnulland this list does not permitnullelements.
In other words, what you are seeing is specified behavior … and not a result of an incorrect or capricious implementation.
For the case where you are searching countryList … it will depend on the actual List implementation class. But there is a clear expectation in the List spec for contains that some kinds of list may throw an NPE if you try to search for null.
(Whether that is a “poor design choice” or not is a matter of opinion. But it is moot. The List design choices were made a long time ago and changing them would now would be too disruptive to contemplate. Besides, I doubt that you would convince the current Java design team that null values in collection types are a good idea.)