[英]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>>
您可以将一个人为的问题放在另一个之上。
任何Collection
本身都可以通过为空来表示数据的缺失。 您可以安全地与空集合进行交互。 用Optional
包装它是多余的。
这里引用了Brian Goetz的回答,Java 语言架构师,关于Optional
的使用方式,以及从其创建者的角度来看不应该如何使用它:
我们的目的是为库方法返回类型提供一种有限的机制,在这种情况下需要一种明确的方式来表示“无结果” ,并且使用
null
有可能导致错误。例如,您可能永远不应该将它用于返回结果数组或结果列表的东西; 而是返回一个空数组或列表。
结论:第一个 API 返回Optional<List<Integer>>
的设计不正确。
这被认为是对 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.