Java 从 Optional<> 转换为 ArrayList<>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31688382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cast from Optional<> to ArrayList<>
提问by user3097712
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>
.
所以,我的问题是b.c.test()
返回一个Optional<A>
返回类型的值。但我需要返回一个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.
但是 Eclipse 说这种从Optional<A>
to 转换ArrayList<A>
是不可能的。
How can I solve this problem?
我怎么解决这个问题?
回答by sprinter
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
.
但是,我建议您的返回类型应该是,List<A>
而不是ArrayList<A>
因为这让您有机会在不更改调用者的情况下更改列表类型。Collections.EMPTY_LIST
如果不存在可选值,它也将允许您返回,这比创建不必要的ArrayList
.
Update: there's now an easier option with Java 9:
更新:Java 9 现在有一个更简单的选择:
b.c.test().stream().collect(Collectors.toList());
回答by John Kugelman
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.
如果可选项有一个值,它“映射”到一个List<A>
withArrays.asList
然后到一个ArrayList
vianew ArrayList<A>(List<A>)
构造函数;否则它会ArrayList
通过空构造函数产生一个空值。
This could be more explicitly written out as:
这可以更明确地写成:
return b.c.test()
.map(value -> new ArrayList<A>(Arrays.asList(value)))
.orElseGet(() -> new ArrayList<A>());
回答by Anonymous Coward
An Optional is a container object which may or may not contain a non-null value.
Optional 是一个容器对象,它可能包含也可能不包含非空值。
In ArrayList terms I would translate it as an array which has 0 or 1 members.
在 ArrayList 术语中,我会将其翻译为具有 0 或 1 个成员的数组。
public ArrayList<A> getMethods(){
Optional<A> opt = b.c.test();
ArrayList<A> res = new ArrayList<>();
if ( opt.isPresent() )
res.add( opt.get() );
return res;
}
回答by dimo414
If you're using Guava's Optional
, you can do:
如果您使用的是 Guava's Optional
,您可以执行以下操作:
return new ArrayList<>(b.c.test().asSet());
This will extract the value from the Optional
(if present) and add it to a new ArrayList
.
这将从Optional
(如果存在)中提取值并将其添加到新的ArrayList
.
If you're using Java 8, @sprinter's answer is what you need.
如果您使用的是 Java 8,@sprinter 的答案就是您所需要的。
回答by user140547
If everyone insists on using streams for this issue, it should be more idiomatic than using ifPresent()
Unfortunately, Java 8 does not have a Optional.stream()
method, so it is not possible to do:
如果每个人都坚持使用流来解决这个问题,应该比使用更惯用ifPresent()
不幸的是,Java 8 没有Optional.stream()
方法,因此无法做到:
optional.stream().collect(Collectors.toList());
see also: Using Java 8's Optional with Stream::flatMap
另请参阅:将 Java 8 的 Optional 与 Stream::flatMap 一起使用
But in JDK 9, it will be added (and that code actually already runs on Java 9)
但是在 JDK 9 中,它将被添加(并且该代码实际上已经在 Java 9 上运行)
Optional<Integer> o = Optional.empty();
final List<Integer> list = o.stream().collect(Collectors.toList());
System.out.println(list);
回答by Niraj Sonawane
With Java9,you can do this using the newly added Optional::stream API
:
使用 Java9,您可以使用新添加的Optional::stream API
:
Optional<List<A>> list;
List<A> collect = list.stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());
回答by Roland Illig
In this case, it is possible to 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:
或者,使用函数式 API 的相同代码:
public static <T> List<T> toList(Optional<T> opt) {
return opt
.map(Collections::singletonList)
.orElseGet(Collections::emptyList);
}
I prefer the upper variant because I know for sure that it doesn't create any unnecessary objects on the Java heap.
我更喜欢上层变体,因为我确信它不会在 Java 堆上创建任何不必要的对象。