Send from optional <> to ArrayList <>
I have the following situation:
public ArrayList<A> getMethods(){ return b.c.test(); }
So my problem is what is b.c.test()
returning value with Optional<A>
as return type. But I need to return ArrayList<A>
.
So, I tried to do this and rewrite it to:
public ArrayList<A> getMethods(){ return (ArrayList<A>)b.c.test(); }
But Eclipse says that such selection from Optional<A>
to ArrayList<A>
cannot be .
How can I solve this problem?
source share
I assume your intended semantics are "if value is present, return a list with one element, otherwise return an empty list". In this case, I would suggest the following:
ArrayList<A> result = new ArrayList<>(); b.c.test().ifPresent(result::add); return result;
However, I would suggest that your return type should be List<A>
, not ArrayList<A>
as it gives you the ability to change the type of the list without changing the callers. This will also allow you to return Collections.EMPTY_LIST
if the optional value is missing, which is more efficient than creating an unnecessary one ArrayList
.
Update : There is now a simpler option as of Java 9:
b.c.test().stream().collect(Collectors.toList());
source share
If everyone insists on using streams for this problem, it should be more idiomatic than using ifPresent()
Unfortunately Java 8 does not have a method Optional.stream()
, so this cannot be done:
optional.stream().collect(Collectors.toList());
see also: Using Java 8 Options with Stream :: flatMap
But in JDK 9 it will be added (and this code already works in Java 9)
Optional<Integer> o = Optional.empty(); final List<Integer> list = o.stream().collect(Collectors.toList()); System.out.println(list);
source share
return b.c.test() .map(Arrays::asList).map(ArrayList::new) .orElseGet(ArrayList::new);
If the parameter has a value, it "maps" it to List<A>
s Arrays.asList
and then ArrayList
to using the constructor new ArrayList<A>(List<A>)
; otherwise, an ArrayList
empty constructor is returned empty.
This could be more explicitly written as:
return b.c.test() .map(value -> new ArrayList<A>(Arrays.asList(value))) .orElseGet(() -> new ArrayList<A>());
source share
Optional is a container object that may or may not contain a nonzero value.
In terms of ArrayList, I would translate it as an array that has 0 or 1 member.
public ArrayList<A> getMethods(){ Optional<A> opt = b.c.test(); ArrayList<A> res = new ArrayList<>(); if ( opt.isPresent() ) res.add( opt.get() ); return res; }
source share
In this case, you can not use streams at all:
public static <T> List<T> toList(Optional<T> opt) { return opt.isPresent() ? Collections.singletonList(opt.get()) : Collections.emptyList(); }
Or the same code using the functional API:
public static <T> List<T> toList(Optional<T> opt) { return opt .map(Collections::singletonList) .orElseGet(Collections::emptyList); }
I prefer the top option because I know for sure that it doesn't create unnecessary objects on the Java heap.
source share