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