Dealing with a null attribute using java 8 streams and sorting using lambda expressions
Solution 1
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;
Solution 2
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.
Solution 3
Try pre-filtering for non-null parentId
values only:
result = list.stream().filter(e -> e.getParentId() != null).filter(predicate).collect(Collectors.toList());
[edit]
Just saw, that the attribute (e.parentId
) seems the one being null
. In that case, the second thing, the sorting, breaks. You are sorting the original list, not the filtered one. Try result.sort(comp)
, then you should avoid the NPE.
Solution 4
You can do it all in one Stream pipeline :
List<Entity> result =
list.stream()
.filter(e -> e.getParentId()!=null) // it's not clear if the null
// is the Entity object itself
// (in which case it should be e!=null)
// or just the ParentId member
.filter(predicate)
.sorted(comp)
.collect(Collectors.toList());
BTW, according to the text of your question, the original predicate should be :
Predicate<Entity> predicate = e -> e.getParentId() > 100; // not < 100
Solution 5
Harness the power of a method reference to make the code even more compact:
List<Entity> result =
list.stream()
.filter(Objects::nonNull)
.filter(predicate)
.sorted(comp)
.collect(Collectors.toList());
Related videos on Youtube
Manu Joy
Updated on January 25, 2020Comments
-
Manu Joy over 4 years
Let's consider a
Parent
class which contains only oneInteger
attribute. I created 6 objects of parent class and values of attribute are100, 20, 300, 400, 500, null
.Now I added all the objects to a list(Name of list is list). Then I want to get the objects whose attribute value is greater than
100
. I used Java 8 streams for this purpose.Predicate<Entity> predicate = e -> e.getParentId() < 100; result = list.stream().filter(predicate).collect(Collectors.toList());
I also want to sort the list in descending order. I used the following code for this purpose.
Comparator<Entity> comp = (d1,d2) -> d2.getId().compareTo(d1.getId()); list.sort(comp);
In both cases I get a
NullPointerException
.How to handle this?
-
Nir Alfasi almost 9 yearspossible duplicate of How should we manage jdk8 stream for null values
-
ajb almost 9 yearsI'm unclear... is it
e
that isnull
, ore.getParentId()
? Ife.getParentId()
is declared as anInteger
(the boxed type), it may be null. But then when it's converted to anint
to compare it to 100, the result will be aNullPointerException
if it'snull
.
-