我正在使用Stream.reduce()
進行試驗,並且遇到了類型系統的問題。這裏有一個玩具例子:使用通配符類型減少數據流
public static Number reduceNum1(List<Number> nums) {
return nums.stream().reduce(0, (a, b) -> a);
}
這適用於任何List<Number>
,但如果我希望能夠減少一個列表,? extends Number
什麼?這並不編譯:
public static Number reduceNum2(List<? extends Number> nums) {
return nums.stream().reduce((Number)0, (a, b) -> a);
}
與錯誤:
ReduceTest.java:72: error: no suitable method found for reduce(Number,(a,b)->a)
return nums.stream().reduce((Number)0, (a, b) -> a);
^
method Stream.reduce(CAP#1,BinaryOperator<CAP#1>) is not applicable
(argument mismatch; Number cannot be converted to CAP#1)
method Stream.<U>reduce(U,BiFunction<U,? super CAP#1,U>,BinaryOperator<U>) is not applicable
(cannot infer type-variable(s) U
(actual and formal argument lists differ in length))
where U,T are type-variables:
U extends Object declared in method <U>reduce(U,BiFunction<U,? super T,U>,BinaryOperator<U>)
T extends Object declared in interface Stream
where CAP#1 is a fresh type-variable:
CAP#1 extends Number from capture of ? extends Number
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
我得到的,在概念,爲什麼出現這種情況。 Stream.reduce()
必須返回與源元素相同類型的東西,並且? extends Number
與Number
不同。但我不確定如何處理這種情況。我如何允許減少(或收集)子類的集合(例如List<Integer>
)?
如果有幫助,下面是同樣無法編譯一個更實際的例子:
public static <E> Set<E> reduceSet1(List<? extends Set<E>> sets) {
return sets.stream().reduce(ImmutableSet.<E>of(), (a, b) -> Sets.union(a, b));
}
@SotiriosDelimanolis不直接,但偉大的建議!我會更多地發表一個答案。 – dimo414
如果你的參數是一個BigDecimals列表,那麼'(Number)0'是什麼意思? – assylias
@assylias取決於可能導致問題的累加器函數,但在這種情況下它不應該 - 我想要某種'Number',不一定是'BigDecimal'。 'Set'示例可能會澄清何時這可能有用。我想返回某種'Set',我不在乎它是什麼實現。 – dimo414