JB Nizet answer is okay, but it uses map only for its side effects and not for the mapping operation, which is kind of weird. There is a method which can be used when you are solely interested in the side effects of something, such as throwing an exception: peek.
List<Parent> filtered = list.stream()
.peek(Objects::requireNonNull)
.filter(predicate)
.collect(Collectors.toList());
And if you want your own exception just put a lambda in there:
List<Parent> filtered = list.stream()
.peek(p -> { if (p == null) throw new MyException(); })
.filter(predicate)
.collect(Collectors.toList());
Note about non exhausted streams
Note that, regardless of if you use map or peek, you have to make sure that the stream is consumed in its entirety for all the elements to be checked! Otherwise the exception might not be thrown even if there are null elements.
Examples where all elements might not be checked:
limitis used.allMatchis used.- The stream is filtered BEFORE the null check pipeline stage.
Checked Exceptions
If your exception is checked you can either check for null beforehand, if you don't mind traversing the list twice. This is probably best in your case, but might not always be possible.
if (list.contains(null)) throw new MyCheckedException();
You could also throw an unchecked exception in your stream pipeline, catch it and then throw the checked one:
try {
...
.peek(p -> { if (p == null) throw new MyException(); })
...
} catch (MyException exc) {
throw new MyCheckedException();
}
Answer from Lii on Stack OverflowJB Nizet answer is okay, but it uses map only for its side effects and not for the mapping operation, which is kind of weird. There is a method which can be used when you are solely interested in the side effects of something, such as throwing an exception: peek.
List<Parent> filtered = list.stream()
.peek(Objects::requireNonNull)
.filter(predicate)
.collect(Collectors.toList());
And if you want your own exception just put a lambda in there:
List<Parent> filtered = list.stream()
.peek(p -> { if (p == null) throw new MyException(); })
.filter(predicate)
.collect(Collectors.toList());
Note about non exhausted streams
Note that, regardless of if you use map or peek, you have to make sure that the stream is consumed in its entirety for all the elements to be checked! Otherwise the exception might not be thrown even if there are null elements.
Examples where all elements might not be checked:
limitis used.allMatchis used.- The stream is filtered BEFORE the null check pipeline stage.
Checked Exceptions
If your exception is checked you can either check for null beforehand, if you don't mind traversing the list twice. This is probably best in your case, but might not always be possible.
if (list.contains(null)) throw new MyCheckedException();
You could also throw an unchecked exception in your stream pipeline, catch it and then throw the checked one:
try {
...
.peek(p -> { if (p == null) throw new MyException(); })
...
} catch (MyException exc) {
throw new MyCheckedException();
}
Let’s start with the simplest solution:
if(list.contains(null)) throw new MyException();
result = list.stream().filter(predicate).collect(Collectors.toList());
If you suspect the list to contain nulls and even have a specialized exception type to flag this condition, a pre-check is the cleanest solution. This ensures that such condition doesn’t silently remain if the predicate changes to something that can handle nulls or when you use a short-circuiting stream operation that may end before encountering a subsequent null.
If the occurrence of null in the list still is considered a programming error that shouldn’t happen, but you just want to change the exception type (I can’t imagine a real reason for this), you may just catch and translate the exception:
try {
result = list.stream().filter(predicate).collect(Collectors.toList());
}
catch(NullPointerException ex) {
if(list.contains(null)) // ensure that we don’t hide another programming error
throw new MyException();
else throw ex;
}
This works efficient under the assumption that null references do not occur. As said, if you suspect the list to contain null you should prefer a pre-check.
Looks like you are looking for something like:
list.sort(Comparator.comparing(Entity::getParent,
Comparator.nullsLast(Integer::compareTo)));
All the elements with parent null will be put at the end and the rest will be sorted by their parent.
All of the answers here revolve around "throw out the bad elements, those that have a null getParentId()." That may be the answer, if they are indeed bad. But there's another alternative: Comparators.nullsFirst (or last.) This allows you to compare things treating a null value as being less than (or greater than) all non-null values, so you don't have to throw the elements with a null parentId away.
Comparator<Entity> cmp = nullsLast(comparing(Entity::getParentId));
List<Entity> list = list.stream().sorted(cmp).collect(toList());
You can do a similar thing for filtering; define your predicate as:
Predicate<Entity> predicate = e -> e.getParentId() != null
&& e.getParentId() < 100;
The issue was: I was using .isEmpty() on a null object. I had to use StringUtils.isEmpty() method:
services = services.stream()
.filter(service -> (StringUtils.isEmpty(service.getType()) || service.getType().equals(type)))
.collect(Collectors.toList());
Too late for an answer but still posting this here if anyone comes across this post.
Try to use filter out all the objects which are null or have some property that can be null, before performing any operations on the same.
In this case
list.stream()
//.filter(Objects::nonNull) // use when the whole object can be null
.filter(service->Objects.nonNull(service.getType()))
.filter(service -> (service.getType().isEmpty() || service.getType().equals("Type1")))
.collect(Collectors.toList());
You shouldn't call get() on your Optionals - and when you use Optional.map you have a nice way to wrap a null result from a Map get into another Optional:
Optional<PTerms> dealPricingTerms = dDetails
.getDealCommits().map(c -> c.get(cNumber))
.flatMap(dc -> dc.getPTerms())
.map(l -> l.stream())
.flatMap(s ->
s.filter(dealPricingTerm ->
tMonth.equals(dealPricingTerm.getDeliveryPeriod()))
.findFirst());
You have to add filter to check null before your condition filter.
.filter(Objects::nonNull)
for example,
List<String> carsFiltered = Optional.ofNullable(cars)
.orElseGet(Collections::emptyList)
.stream()
.filter(Objects::nonNull) //filtering car object that are null
.map(Car::getName) //now it's a stream of Strings
.filter(Objects::nonNull) //filtering null in Strings
.filter(name -> name.startsWith("M"))
.collect(Collectors.toList()); //back to List of Strings