Issue
Consider I have an array list of Optional
objects like List<Visit> visit = {Optional[Visit], Optional[Visit], ...}
. How do i get the Visit
object from the Optional
and just return those objects as a List
?
I tried something like this:
return Stream.of(visits).filter(value -> Optional.isPresent(value))
.map((Visit t) -> Optional.get(t))
.collect(Collectors.toList());
and this:
return Stream.of(visits)
.map(visit -> Optional.of(visit).get())
.collect(Collectors.toList());
But this doesn't compile.
I am trying to use Lightweight-Stream-API as the stream library.
Solution
You may do it this way:
return visits.stream()
.map(visit -> visit.orElse(null))
.filter(Objects::nonNull)
.collect(Collectors.toList());
Assuming visits
is of type List<Optional<Visit>>
.
Causes Of Your Code Not Compiling
Assuming that the variable visits
is of type List<Optional<Visit>>
the statement you posted:
Stream.of(visits).filter(value -> Optional.isPresent(value))
.map((Visit t) -> Optional.get(t))
.collect(Collectors.toList());
has the following problems:
Stream.of()
takes either one element or many elements of typeT
and creates a Stream. You usevisits
as one element of typeList<Optional<Visit>>
and I think you intend to get a Stream ofOptional<Visit>
which you may achieve by usingvisits.stream()
.filter(value -> Optional.isPresent(value))
does invokeisPresent(T t)
in a static way while the methodisPresent(T t)
doesn't exist, neither statically nor as an instance method. I think what you intend to do is:filter(value -> value.isPresent())
which is equal tofilter(Optional::isPresent)
. The difference of the second is thatOptional::isPresent
does not invoke a static method but results in a method reference.map((Visit) t -> Optional.get(t))
does as well invoke a methodget(T t)
in a static way which doesn't exist, neither statically nor as an instance method. I think you intended to invokemap((Visit) t -> t.get())
which is equal tomap(Optional::get)
.
Fixing those issues would result in the new statement:
visits.stream().filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
The difference to my solution is only that you map after filter. As a reader to get it right you need to remember that Optional::get
will always return a non-null value. If you map first and filter second you do not have to remember there are no null
values because you filter them out in the second step.
Answered By - Harmlezz