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.of
methods are specified as producing unmodifiable lists.Unmodifiable lists are specified to not permit
null
elements:“They disallow null elements. Attempts to create them with
null
elements result inNullPointerException
.”The javadoc for
List.contains
states:“Throws:
NullPointerException
– if the specified element isnull
and this list does not permitnull
elements.
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.)