一個解決它的方法是使用一種類型的參數:
public <I extends Image> I findMainImage(Collection<I> images) {
if (images == null || images.isEmpty()) return null;
return images.stream()
.filter(Image::isMain)
.findFirst()
.orElse(images.iterator().next());
}
因爲然後(編譯器)的絕對Optional
具有相同類型參數作爲images
。
而且我們可以使用,作爲一個capturing helper如果我們想:
public Image findMainImage(Collection<? extends Image> images) {
return findMainImageHelper(images);
}
private <I extends Image> I findMainImageHelper(Collection<I> images) {
// ...
}
就個人而言,我只是將使用通用版本,因爲那麼你可以做如:
List<ImageSub> list = ...;
ImageSub main = findMainImage(list);
基本上......爲什麼最初不編譯的原因是爲了避免你這樣做:
public Image findMainImage(
Collection<? extends Image> images1,
Collection<? extends Image> images2
) {
return images1.stream()
.filter(Image::isMain)
.findFirst()
.orElse(images2.iterator().next());
}
而在原始示例中,編譯器不需要確定事實:Stream
和Iterator
來自同一個對象。引用相同對象的兩個單獨的表達式被捕獲到兩個單獨的類型。
這可能會工作,如果它只是一個'集合',但泛型的工作方式,'可選。或Else'只能接受'T'。 –
您可以將方法簽名更改爲'public T findMainImage(Collection images)' –
Misha
@misha我通過更改簽名來了解它的工作原理,我更感興趣的是理解此背後的推理。 – sanz