Reputation: 6063
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.
Upvotes: -1
Views: 3021
Reputation: 8068
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 type T
and creates a Stream. You use visits
as one element of type List<Optional<Visit>>
and I think you intend to get a Stream of Optional<Visit>
which you may achieve by using visits.stream()
.
filter(value -> Optional.isPresent(value))
does invoke isPresent(T t)
in a static way while the method isPresent(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 to filter(Optional::isPresent)
. The difference of the second is that Optional::isPresent
does not invoke a static method but results in a method reference.
map((Visit) t -> Optional.get(t))
does as well invoke a method get(T t)
in a static way which doesn't exist, neither statically nor as an instance method. I think you intended to invoke map((Visit) t -> t.get())
which is equal to map(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.
Upvotes: 5
Reputation: 34460
You could do it as follows:
List<Visit> visitsWithoutOptionals = visits.stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
Upvotes: 4