[英]Java 8 generic collections with optionals
我有一个相对简单的问题,我试图解决。 似乎没有直观的方法来做到这一点,或者我在这里遗漏了一些东西。
考虑使用此方法查找主图像,如果不存在,则返回第一张图像 -
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
任何方向都会很棒。
解决它的一种方法是使用类型参数:
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
相同的类型参数。
如果我们想要,我们可以将其用作捕获助手 :
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
都来自同一对象的事实。 引用同一对象的两个单独表达式被捕获到两个不同的类型。
假设你有一个List<? extends Number>
List<? extends Number>
。 您无法在此列表中添加任何数字,因为它可能是List<Integer>
,您尝试添加的数字可能是Float
。
出于同样的原因, Optional<T>
的方法orElse(T t)
需要T
由于Optional
的问题是一个Optional<? extends Image>
Optional<? extends Image>
,编译器无法确定images.iterator().next()
是否为正确的类型。
我通过放入.map(t -> (Image) t)
来编译它:
return images.stream()
.filter(Image::isMain)
.findFirst()
.map(t -> (Image) t)
.orElse(images.iterator().next());
事实上,由于某种原因,我无法理解,即使没有演员,它也能奏效。 只是用
.map(t -> t)
似乎使这项工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.