0

I have a List of objects and want to get the last element from List for which property "personStatus" value is not null.

List<Person> personList = getAllPersons(); List<Person> personActive = personList.stream().filter(person -> person.getPersonStatus()!=null); 

I tried the above code which gives List of Person whose status is not null, but i want to get the last Person object with status not null.

3

2 Answers 2

0

You solved 80%: first collect and filter. This will give a new collection using Java 8 streams.

Literally: last

Then pick the last from the filtered collection, e.g. on list using list.get(lastIndex) where int lastIndex = list.size()-1 .

The last is a bit ambiguous, so I have 2 approaches 😉️

List<Person> personList = getAllPersons(); // typo: name of List should be plural e.g. `personActiveList` or `activePersons` List<Person> personActive = personList.stream() .filter(person -> person.getPersonStatus()!=null) .toList(); // the last in order of appearance Person lastInActiveList = personActice.get(personActice.size()-1); // may throw NPE if list empty // the last who was active by some Instant timestamp List<Person> sortByLastActive = personList.stream() .filter(person -> person.getPersonStatus()!=null) .sorted(Person::getTimestamp()) # sort by Instant property .toList(); Person lastRecentlyActice = sortByLastActive.get(sortByLastActive.size()-1); // may throw NPE if list empty 

Note: For brevity I used toList() as terminator (since Java 16).

You could also use collect(Collectors.toList()) from older Java versions. Beware: Differences of Java 16's Stream.toList() and Stream.collect(Collectors.toList())?

⚠️ Caution: all random get operations on list can throw a NullPointerException (NPE) if the list is empty. This should be tested using if (list.isEmpty()) before to prevent illegal access.

Trick: reverse to first

The trick here as commented by Boris is to reverse the list before opening the stream, thus before it becomes filtered/collected as result. Afterwards you can directly pick the first.

List<Person> personActiveReversed = Collections.reverse(personList).stream() // reverse to get last elements first .filter(person -> person.getPersonStatus()!=null) .toList(); // may throw NPE if list empty Person last = personActiveReversed.get(0); // safer: directly on stream Optional<Person> last = Collections.reverse(personList).stream() // reverse before streaming .filter(person -> person.getPersonStatus()!=null) .findFirst(); // originally the last or empty // evaluate optional if (last.isPresent()) { System.out.println("found the last: " + last.get()); } else { System.out.println("nobody found at last :("); } 

Explained:

  • see comments by Boris below and on question: use Collections.reverse before .stream to reverse an ordered list (from last to first). Then reversedList.get(0) will get the originally last element.

  • findFirst() is the new terminator, returning Java 8 type-wrapper Optional. This is null-safe but requires a further test or convenience-methods like orElse(defaultObject), e.g. last.orElse(null).

See also

Sign up to request clarification or add additional context in comments.

2 Comments

Your comparator is invalid, it needs to be symmetric - otherwise sorting behaviour is undefined and can throw and error.
This has nothing to do with “sequential”. The broken comparator happens to provide the intended result due to implementation details of the sorting algorithm used behind the scenes. Since this sorting algorithm is intentionally unspecified, this comparator may produce unintended results in a different implementation or fail with an exception, regardless of whether the Stream is sequential or not. A well known example of the past were broken comparators failing with exceptions when Java 7 was introduced. Some occurrences might be here
-1
int lastNotNull = -1; for(int i = 0; i < personList.size();i++){ if(person.getPersonStatus()!=null) lastNotNull = i; } 

lastNotNull is the index of the last not null Person

1 Comment

Hint: if you search the other way you can terminate early.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.