[英]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.