Ole*_*.V. 0 java raw-types generic-collections type-parameter java-stream
我正在调用一个返回 raw 的库方法Stream
。我知道流中元素的类型,并希望将其收集到具有声明元素类型的集合中。什么是好的或不那么骇人听闻的做法?
为了一个可重现的例子,假设我想调用这个方法:
@SuppressWarnings("rawtypes")
static Stream getStream() {
return Stream.of("Example");
}
Run Code Online (Sandbox Code Playgroud)
我曾希望这会起作用,但我不明白为什么它不起作用:
List<String> stringList = getStream().map(s -> (String) s).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
我得到Type mismatch: cannot convert from Object to List。为什么?
未经检查的演员阵容有效。为了缩小需要标记为故意未检查的位,我们可以这样做
@SuppressWarnings("unchecked")
Stream<String> stringStream = getStream();
List<String> stringList = stringStream.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
在 Java 8 和 Java 11 上,返回的列表都是 a java.util.ArrayList
,它包含预期的String
元素。
我尝试使用我的搜索引擎搜索诸如java collect raw stream 之类的术语。它没有让我找到任何有用的东西。有一个封闭的 Java 错误(底部的链接)提到一旦您对原始类型进行操作,一切都会变得原始。但是这个完全原始的版本也不起作用:
List stringList = getStream().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
我仍然遇到Type mismatch: cannot convert from Object to List。怎么来的?
我们正在为 Java 8 编码(还有一段时间)。
我知道这个问题有一些基于意见的东西。我仍然希望你能向我提供一些事实,以帮助我编写通常被认为更好的代码。
我要调用的方法是org.hibernate.query.Query.getResultStream()
原始的Query
(Query
缺少类型参数)。我想获取流,因为我对收集的集合类型有特殊要求。在我正在使用的生产代码中Collectors.toCollection()
(而不是Collectors.toLlist()
在这个问题的示例中)。顺便说一句,在写这个问题时,我找到了一种说服 Hibernate 返回类型化流的方法。我仍然觉得这个问题很有趣,可以发帖。
提示在 Java Bug 记录中,好吧:一旦我使用原始类型,一切都会变得原始。Stream.collect()
也是一个泛型方法,所以它的原始版本返回 — Object
,不要感到惊讶。
Stream
我正在调用的方法声明如下:
<R,A> R collect?(Collector<? super T,A,R> collector)
Run Code Online (Sandbox Code Playgroud)
所以它返回一个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);
Run Code Online (Sandbox Code Playgroud)
Java 11 上的输出:
Run Code Online (Sandbox Code Playgroud)class java.util.ArrayList [Example]
强制Stream
转换Stream<?>
(隐式或显式)无需未经检查的操作即可摆脱原始类型。之后map()
可以按预期使用。并且不需要@SuppressWarnings("unchecked")
.
这也意味着我原来的 Hibernate 场景的解决方案是在调用之前将Query
对象强制转换为 a而不是只强制转换流。然后以与上述相同的方式在流操作中将每个单独的对象投射到 a中。Query<?>
getResultStream()
map()
归档时间: |
|
查看次数: |
308 次 |
最近记录: |