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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:25:52  来源:igfitidea点击:

Cast from Optional<> to ArrayList<>

javaarraylistcastingoptional

提问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_LISTif 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.asListand then to an ArrayListvia the new ArrayList<A>(List<A>)constructor; otherwise it yields an empty ArrayListvia the empty constructor.

如果可选项有一个值,它“映射”到一个List<A>withArrays.asList然后到一个ArrayListvianew 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 中,它将被添加(并且该代码实际上已经在 J​​ava 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 堆上创建任何不必要的对象。