java - 使用 Stream API 进行转换

标签 java generics casting java-8 java-stream

我不确定为什么这段代码无法编译(情况 1)

List list = new LinkedList<>();
List<Long> longList = list.stream()
    .map(value -> (Long) ((Map) value).get("id"))
    .collect(Collectors.toList());

但是这段代码编译成功(情况2)

List list = new LinkedList<>();

Stream<Long> longStream = list.stream()
    .map(value -> (Long) ((Map) value).get("id"));

List<Long> longList = longStream.collect(Collectors.toList());

此代码成功编译为(情况 3)

List<Object> list = new LinkedList<>();
List<Long> longList = list.stream()
    .map(value -> (Long) ((Map) value).get("id"))
    .collect(Collectors.toList());

我的同事认为这与

Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.

来自 Java SE tutorial

因此,如果第 1 个列表是无界的,这就是编译器将所有类型替换为 Object 的原因。

在情况 2 中,我们创建了 Long 的通用 Stream,并且该流不能是无界的。编译器什么也不做。

在情况 3 中,我们有 ObjectList,并且在编译期间没有替换。

问题是这三种情况的真正区别是什么?

最佳答案

您的List list是原始类型,这会使您调用它的所有方法也成为原始类型,即使您稍后可能返回泛型类型。也就是说,您 map() 名义上返回 Stream<Long>但编译器只将其视为非泛型 Stream

通过将其分配给变量,您可以有效地将其转换为泛型。

我建议你做的是

List<Map<String, Long>> list = new LinkedList<>();
List<Long> longList = list.stream()
    .map(value -> value.get("id"))
    .collect(Collectors.toList());

关于java - 使用 Stream API 进行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28328663/

相关文章:

java - 抽象类上参数化方法的奇怪行为

generics - 如何创建一个可以用 Serde 序列化并保留类型信息的通用结构?

c# - 类型转换和 'as' 转换之间的区别

c++ - 类型转换会导致问题吗?

java - hibernate 更新不起作用

c# - 在 Lazy<T> 中转换接口(interface)类型

java - struts 2 标签不会生成标签

ios - 无法将类型 '() -> Void' 的值分配给 '(() -> Void)!'

java - Month.AUGUST 中的 dayOfMonth(31)

java - 自 JDK 6 以来,Java 内存使用情况是否有所改善?