Hi guys, I'm a little stuck with something here.
Basically I have a a method which, given a List of Students will have to filter out those who are younger than 60yrs old and should return a List of Students who are over 60yrs old but I want this to be a list of Optionals rather than just a List of Students. THe difficulty is that I can't find a way to return a list of optionals like List<Optional>. I can return an optional if I use things like findFirst() or findAny()
return studentList.stream().filter(x -> x.getAge() > 60).findAny();
or i could return a simple list of students
return studentList.stream().filter(x -> x.getAge() > 60).collect(Collectors.toList());
but I want all the Students over 60 in a list of Optional.
Any idea how that can be done if it can be done that is?
thanks

Something like this should give you enough info...

Stream<Integer> si = Stream.of(1, 2, 3, 4, 5);
List<Optional<Integer>> result = si.filter(i -> i < 4).
map(i -> Optional.of(i)).
collect(Collectors.toList());
System.out.println(result);

map(s -> Optional.of(s)) is transforming those objects into Optionals, correct?

Yes, but more accuratel: .map creates a new Stream from the values returned by the lambda.

There are probably other ways to do it, but this is a really obvious and easy-to-read solution.

All 4 Replies

Something like this should give you enough info...

Stream<Integer> si = Stream.of(1, 2, 3, 4, 5);
List<Optional<Integer>> result = si.filter(i -> i < 4).
map(i -> Optional.of(i)).
collect(Collectors.toList());
System.out.println(result);

Right. Thanks. I've implemented the functionality based on your example and yes it works. Now I have to make sure I understand it though.
Let's look at the code (I will return it directly rather than returning the variable).
studentList here is a List type.

private List<Optional<Student>> getOverSixtyStudents() {
List<Optional<Student>> collect = studentList.stream().
filter(s -> s.getAge() > 60)
.map(s -> Optional.of(s))
.collect(Collectors.toList());
return collect;
}

First off turn studentList to a stream, then apply the filter as before to filter out students below 61. Now, after filter(s -> s.getAge() > 60), "s" contains student objects whose age is above 60, correct?
If that's so, then .map(s -> Optional.of(s)) is transforming those objects into Optionals, correct?
Then the terminal operation .toList() simply turn that into a list.
If all the above is correct, it was actually a lot easier than I thought...but I did't actually thought about using the map to transform the values, I was more hoping to find a way to replace .toList() with something else that would generate Optionals, which was clearly a mistake.

map(s -> Optional.of(s)) is transforming those objects into Optionals, correct?

Yes, but more accuratel: .map creates a new Stream from the values returned by the lambda.

There are probably other ways to do it, but this is a really obvious and easy-to-read solution.

Great, thanks