[英]Different behaviour of jdk8 vs jdk11 when using stream collect
关于流和collect方法,jdk11(及更高版本)的行为确实存在问题。 我确实想要获取参数化容器的值来流式传输资源,并使用.collect(Collectors.toSet())
最终的值。
当我使用jdk8
编译我的代码时,它完全正常。 但是因为我们还必须支持jdk11
,所以我运行了编译并且它失败了因为Error:(136, 17) java: incompatible types: java.lang.Object cannot be converted to java.util.Set<org.bson.types.ObjectId>
jdk11
Error:(136, 17) java: incompatible types: java.lang.Object cannot be converted to java.util.Set<org.bson.types.ObjectId>
(同样适用于openJdk11)
想象一下以下情况。 我有一个基本上是数据容器的类。 此容器可以包含单个值或值列表。
在我的应用程序的某些部分,我有这个容器类的列表(它也可以包含列表作为值),我确实希望通过列表流来获取容器中的所有值作为一个平面列表。
在本例中,我选择使用objectIds列表。
// preparation
List<ObjectId> innerObjects = new ArrayList<>();
innerObjects.add(new ObjectId());
innerObjects.add(new ObjectId());
List<Diamond<Object>> diamonds = new ArrayList<>();
diamonds.add(new Diamond<Object>().value(innerObjects));
public static class Diamond<T> {
private T value;
public Diamond<T> value(T value) {
this.value = value;
return this;
}
public T getValue() {
return this.value;
}
}
Set<ObjectId> objectIdSet = diamonds
.stream()
.filter(diamond -> diamond.getValue() instanceof List)
.map(Diamond::getValue)
.map(List.class::cast)
.flatMap(Collection::stream)
.map(ObjectId.class::cast)
.collect(Collectors.toSet());
Stream<ObjectId> idStream = diamonds
.stream()
.filter(diamond -> diamond.getValue() instanceof List)
.map(Diamond::getValue)
.map(List.class::cast)
.flatMap(Collection::stream)
.map(ObjectId.class::cast);
Set<ObjectId> objectIds = idStream.collect(Collectors.toSet());
但我不明白这是错误的原因。
<deleted as of to be inacurate>
编辑 :我更改了设置代码,以反映我当前的问题。
谁知道我做错了什么?
这可能与JDK-8199234 java8中的代码编译有关,但java9中没有:“不兼容的类型:java.lang.Object无法转换...” ,它被解析为“非问题”并影响Java 9+。
根本原因是在您的示例map(List.class::cast)
执行转换为原始类型List
搞乱有关泛型的信息。 你试图用map(ObjectId.class::cast)
来解决这个问题,但这不是一个好主意。 Streams很大程度上基于泛型,你应该避免手动转换,让编译器推断出类型。
您的代码可以简化为以下,适用于Java 11:
Set<ObjectId> objectIdSet = diamonds.stream()
.filter(Objects::nonNull) // potentially redundant but instanceof was doing it
.map(Diamond::getValue)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.