亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么我在 collect() 之后調用 stream() 時會得到 Stream<Object>?

為什么我在 collect() 之后調用 stream() 時會得到 Stream<Object>?

鴻蒙傳說 2021-10-17 15:43:26
考慮以下未編譯的示例:List<Integer> list = Arrays.asList(1, 2, -3, 8);        list.stream()                .filter(x -> x > 0)                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll)                .stream() // Stream<Object>                .map(x -> x * 2)                .forEach(System.out::println);如果我更換.collect(ArrayList::new, ArrayList::add, ArrayList::addAll)和.collect(Collectors.toList())代碼將被編譯。所以問題是我如何編寫collect()供應商和累加器(我需要它)才能stream()在它之后調用 a ?
查看完整描述

1 回答

?
慕少森

TA貢獻2019條經驗 獲得超9個贊

看來您已經對ArrayList構造函數進行了原始方法引用ArrayList::new。


類型參數不是通過以下方式推斷的:


.collect(ArrayList::new, ArrayList::add, ArrayList::addAll)

所述的3個參數的過載collect預計3個參數,第一個是一個Supplier<R>。此時,collect方法的類型參數R與此處的Twhich之間沒有聯系Integer。推斷這一點的唯一方法是通過第二個參數 a BiConsumer<R, ? super T>。在這里,您有ArrayList::add,這使編譯器也無法進行推斷R。


您必須提供R第一個參數中的內容,即供應商。您可以向類提供顯式類型參數以在方法引用上創建。


.collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll)

這將編譯,并且輸出符合預期:


2

4

16

當您使用 時Collectors.toList(),您只提供一個參數。


public static <T> Collector<T,?,List<T>> toList()


在這里,只有一個類型參數T,因此編譯器可以正確推斷出這T是Integer,因此List<Integer>創建了 a ,從而允許代碼編譯。Collector返回的綁定T到的類型參數List<T>,允許編譯器執行類型推斷。


請注意,這只是首先需要的,因為沒有目標類型可以幫助進行類型推斷;您繼續進行流操作并System.out.println在最后調用,這可以采用Object.


如果你有這個代碼:


List<Integer> modified = list.stream()

            .filter(x -> x > 0)

            .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

然后目標類型推斷將提供Integer給 的類型參數ArrayList::new。這也編譯。


查看完整回答
反對 回復 2021-10-17
  • 1 回答
  • 0 關注
  • 252 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號