【发布时间】:2015-04-24 22:41:34
【问题描述】:
我正在尝试解决一个看起来相对简单的问题。似乎没有一种直观的方法可以做到这一点,或者我在这里遗漏了一些东西。
考虑这种方法来查找主图像,如果不存在,则返回第一张图像-
public Image findMainImage(Collection<? extends Image> images) {
if (images == null || images.isEmpty()) return null
return images.stream()
.filter(Image::isMain)
.findFirst()
.orElse(images.iterator().next())
}
我收到一个错误 - orElse(capture<? extends Image>) in Optional cannot be applied
这方面的任何方向都会很棒。
【问题讨论】:
-
如果它只是
Collection<Image>,这可能会起作用,但泛型的工作方式,Optional<T>.orElse只能接受T。 -
能不能把方法签名改成
public<T extends Image> T findMainImage(Collection<T> images) -
@misha 我通过更改签名了解了它的工作原理,我更感兴趣的是了解这背后的原因。
-
如果您使用带有通配符子类型 (
? extends ...) 的集合的返回值,而不将其绑定到确定类型(例如,通过将其分配给类型为Image的变量,您'会有一个? extends Image类型,而orElse方法由于类型推断需要Image。Java 泛型是一种痛苦,尤其是在涉及通配符时。 -
@sanz 推理是你知道参数化流的
? extends Image与images.iterator().next()产生的? extends Image相同,但编译器不知道.通过更改签名并为集合参数命名,您可以向编译器证明它在两个地方都是相同的类型。
标签: java generics java-8 optional bounded-wildcard