繁体   English   中英

如何转换可选<list<integer> &gt; 到可选<arraylist<integer> &gt; </arraylist<integer></list<integer>

[英]How to convert Optional<List<Integer>> to Optional<ArrayList<Integer>>

我尝试执行以下操作,但它不起作用

Optional<List<Integer>> listOne = someAPI.call()
// convert
Optional<ArrayList<Integer>> listTwo = new ArrayList<>(listOne); // doesn't work
Optional<ArrayList<Integer>> listTwo = Optional.of(new ArrayList(listOne)); // also not working

请注意,第一个 API 返回Optional<List> 我需要将Optional<ArrayList>发送到另一个 API。

通过使用Optional<ArrayList<Integer>>您可以将一个人为的问题放在另一个之上。

不要用可选包装 Collections

任何Collection本身都可以通过为来表示数据的缺失 您可以安全地与空集合进行交互。 Optional包装它是多余的。

这里引用了Brian Goetz回答,Java 语言架构师,关于Optional的使用方式,以及从其创建者的角度来看不应该如何使用它:

我们的目的是为库方法返回类型提供一种有限的机制,在这种情况下需要一种明确的方式来表示“无结果” ,并且使用null有可能导致错误。

例如,您可能永远不应该将它用于返回结果数组或结果列表的东西; 而是返回一个空数组列表

结论:第一个 API 返回Optional<List<Integer>>的设计不正确。

不要使用 Optional 作为参数

这被认为是对 Optional 的滥用,因为它违背了 Optional 的主要设计目标(请参阅上面的引文,也可以看看Stuart Marks 、Java 和 OpenJDK 开发人员的答案)。

结论:期望Optional<ArrayList<Integer>>的第二个 API 的设计也是错误的。

针对接口编写代码

利用抽象,针对接口编写代码。 There's no justification for making the code inflexible and capable only of consuming instances of ArrayList because it would not be able to deal with a List produced by Collections.emptyList() , List.of() , Arrays.asList() , Stream.toList()等。

请参阅“编程到接口”是什么意思?

解决问题

如果可以,修复两个端点。 让它们在没有Optional的情况下工作。

如果您无法控制第一个 API 返回可选的,很好,那么不要让问题变得更大 - 修复第二个 API,让它期待 Z157DB7DF530023575515D366C9B672 的列表。 并在调用第二个 API 之前当场解压可选结果。

您可以为此目的使用orElse()

List<Integer> list = someAPI.call().orElse(Collections.emptyList());

如果你不能同时改变这两个 API,那么你就完蛋了。

此外,不是listOne.map(ArrayList::new)创建初始数据的副本,这意味着由于 API 设计不佳,您的系统不会立即进行第二次调用,而是被迫执行额外的步骤。

如果你从这个开始:

 Optional<List<Integer>> optionalList = getFromSomewhere();

您可以像这样转换为Optional<ArrayList<Integer>>

 Optional<ArrayList<Integer>> optionalArrayList = Optional.of(new ArrayList<>(optionalList.get()));

这与您尝试的接近 - Optional.of(new ArrayList(listOne)) - 但您的尝试没有奏效,因为listOne的类型是Optional<List<Integer>> ,而new ArrayList()的构造函数需要一个集合。 如果您调用.get() ,那么您将从 Optional 中获取列表,这对于 ArrayList 构造函数可以正常工作。

您可以像这样转换它:

Optional<ArrayList<Integer>> listTwo = listOne.map(ArrayList::new);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM