簡體   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