提问人:Anonymous 提问时间:1/9/2021 最后编辑:Anonymous 更新时间:3/10/2021 访问量:1471
将原始流收集到类型化集合中?
Collecting a raw stream into a typed collection?
问:
我正在调用一个返回原始 .我知道流中元素的类型,并希望收集到具有声明的元素类型的集合中。什么是好的,或者不那么骇人听闻的方式?Stream
最小可重复性示例
为了一个可重现的例子,假设我想调用这个方法:
@SuppressWarnings("rawtypes")
static Stream getStream() {
return Stream.of("Example");
}
我曾希望这会起作用,但我不明白为什么它不起作用:
List<String> stringList = getStream().map(s -> (String) s).collect(Collectors.toList());
我得到类型不匹配:无法从对象转换为列表。为什么?
解决方法
未经检查的演员表有效。为了缩小需要标记为故意未选中的位的范围,我们可以这样做
@SuppressWarnings("unchecked")
Stream<String> stringStream = getStream();
List<String> stringList = stringStream.collect(Collectors.toList());
在 Java 8 和 Java 11 上,返回的列表是 ,它包含预期的元素。java.util.ArrayList
String
我的搜索结果与否
我尝试了在搜索引擎上搜索 java collect raw stream 等术语。它没有给我带来任何有用的东西。有一个封闭的 Java 错误(底部的链接)提到,一旦你对原始类型进行操作,一切都会变得原始。但是这个完全原始的版本也不起作用:
List stringList = getStream().collect(Collectors.toList());
我仍然遇到类型不匹配:无法从对象转换为列表。怎么会这样?
我们正在为 Java 8 编写代码(还有一段时间)。
我知道这个问题有一些基于意见的东西。我仍然希望你能为我提供一些事实,帮助我编写通常被认为更好的代码。
背景:Hibernate 5
我要调用的方法位于原始方法(缺少类型参数)上。我想获取流,因为我对要收集到的集合类型有特殊要求。在我的生产代码中,我正在使用(不像本问题中的示例)。顺便说一句,在写这个问题时,我找到了一种方法来说服 Hibernate 返回一个类型化流。我仍然觉得这个问题很有趣,可以发布。org.hibernate.query.Query.getResultStream()
Query
Query
Collectors.toCollection()
Collectors.toLlist()
链接
- 在 Java 错误数据库中的 java.util.stream.Stream.map 方法的 lambda 内部强制转换时出现问题
答:
提示在 Java Bug 记录中:一旦我使用原始类型,一切都会变得原始。 也是一个通用方法,所以它的原始版本返回 — ,不要感到惊讶。Stream.collect()
Object
我调用的方法是这样声明的:Stream
<R,A> R collect(Collector<? super T,A,R> collector)
因此,它返回一个 ,以及它可以从传递的收集器(无论是还是一些)中收集到什么。一旦一切都变得原始,推论就不再有效。并返回.R
R
Collectors.toList()
Collectors.toCollection()
collect()
Object
总而言之:泛型是好的。当我无法避免获得原始的东西时,请尽早将其转换为通用对应物。
编辑:感谢 Sweeper 和 Holger 在评论中提供的宝贵意见,这是我的首选解决方案:
Stream<?> wildcardStream = getStream();
List<String> stringList = wildcardStream.map(s -> (String) s)
.collect(Collectors.toList());
System.out.println(stringList.getClass());
System.out.println(stringList);
Java 11 上的输出:
class java.util.ArrayList [Example]
强制转换为(隐式或显式)删除原始类型,而无需未经检查的操作。之后可以按预期使用。而且没有必要.Stream
Stream<?>
map()
@SuppressWarnings("unchecked")
这也意味着,对于我最初的 Hibernate 场景,解决方案是在调用之前将 Query
对象强制转换为 a,而不是只强制转换流。然后以与上述相同的方式在流操作的 map()
中强制转换每个单独的对象。Query<?>
getResultStream()
评论
((Stream<String>)getStream())
javac
Note: Main.java uses unchecked or unsafe operations.
Stream
Stream<?>
map