I have the following situation:
public ArrayList<A> getMethods(){
return b.c.test();
}
So, my problem is that b.c.test()
returns a value with Optional<A>
as return type. But I need to return an ArrayList<A>
.
So, I tried to cast it and rewrite it to :
public ArrayList<A> getMethods(){
return (ArrayList<A>)b.c.test();
}
But Eclipse says that such a cast from Optional<A>
to ArrayList<A>
is not possible.
How can I solve this problem?
答案 0 :(得分:18)
I am presuming your intended semantic is 'if the value is present return a list with a single item, otherwise return an empty list.' In that case I would suggest something like the following:
ArrayList<A> result = new ArrayList<>();
b.c.test().ifPresent(result::add);
return result;
However I would suggest your return type should be List<A>
rather than ArrayList<A>
as that gives you the opportunity to change the type of list without changing the callers. It would also allow you to return Collections.EMPTY_LIST
if the optional value is not present which is more efficient than creating an unnecessary ArrayList
.
Update: there's now an easier option with Java 9:
b.c.test().stream().collect(Collectors.toList());
答案 1 :(得分:3)
If everyone insists on using streams for this issue, it should be more idiomatic than using func usernameIsTaken(username: String) -> Bool {
//bool to see if username is taken
var isTaken: Bool = false
//access PFUsers
var query : PFQuery = PFUser.query()!
query.whereKey("User", equalTo: username)
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) in
if error == nil {
if (objects!.count > 0){
isTaken = true
println("username is taken")
} else {
println("Username is available. ")
}
} else {
println("error")
}
}
return isTaken
}
Unfortunately, Java 8 does not have a ifPresent()
method, so it is not possible to do:
Optional.stream()
see also: Using Java 8's Optional with Stream::flatMap
But in JDK 9, it will be added (and that code actually already runs on Java 9)
optional.stream().collect(Collectors.toList());
答案 2 :(得分:3)
在这种情况下,可以根本不使用流:
public static <T> List<T> toList(Optional<T> opt) {
return opt.isPresent()
? Collections.singletonList(opt.get())
: Collections.emptyList();
}
或者,使用功能API的相同代码:
public static <T> List<T> toList(Optional<T> opt) {
return opt
.map(Collections::singletonList)
.orElseGet(Collections::emptyList);
}
我更喜欢上层变种,因为我确信它不会在Java堆上创建任何不必要的对象。
答案 3 :(得分:2)
return b.c.test()
.map(Arrays::asList).map(ArrayList::new)
.orElseGet(ArrayList::new);
If the optional has a value, it "maps" it to a List<A>
with Arrays.asList
and then to an ArrayList
via the new ArrayList<A>(List<A>)
constructor; otherwise it yields an empty ArrayList
via the empty constructor.
This could be more explicitly written out as:
return b.c.test()
.map(value -> new ArrayList<A>(Arrays.asList(value)))
.orElseGet(() -> new ArrayList<A>());
答案 4 :(得分:0)
An Optional is a container object which may or may not contain a non-null value.
In ArrayList terms I would translate it as an array which has 0 or 1 members.
public ArrayList<A> getMethods(){
Optional<A> opt = b.c.test();
ArrayList<A> res = new ArrayList<>();
if ( opt.isPresent() )
res.add( opt.get() );
return res;
}
答案 5 :(得分:0)
If you're using Guava's Optional
, you can do:
return new ArrayList<>(b.c.test().asSet());
This will extract the value from the Optional
(if present) and add it to a new ArrayList
.
If you're using Java 8, @sprinter's answer is what you need.
答案 6 :(得分:0)
使用Java9 ,您可以使用新添加的Optional::stream API
执行此操作:
Optional<List<A>> list;
List<A> collect = list.stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());