Java如何直接流式处理函数返回的嵌套泛型List<Foo<Map<String,String>>>集合
问题解答
问题根因
你定义的my_data_struct类本身存在未检查泛型转换的安全问题:
- 类内私有成员的泛型类型是
List<Foo<Map<String, Object>>> - 但
getListOfFoo方法的返回值类型是List<Foo<Map<String, String>>>
Java泛型具备不变性,上述两种泛型类型完全不兼容,你直接返回成员变量的写法会触发编译器的未检查转换警告,本身就是不符合规范的写法。
两种写法的编译差异原因:
- 赋值给显式声明泛型的变量时:编译器会将getter返回的未检查转换结果,对齐你声明的
List<Foo<Map<String, String>>>类型做后续推导,所以stream的元素类型可以被正确识别为Foo<Map<String, String>>,可以正常编译。 - 直接链式调用时:因为getter返回值本身是未检查的泛型,编译器会将其识别为原始类型(raw type)的List,stream生成的元素默认是
Object类型,自然无法调用keySet方法,编译失败。
补充:你示例代码里的lambda参数命名存在笔误,List内存储的是
Foo对象而非Map,需要先调用Foo类中获取内部Map的方法,才能调用keySet。
无需提前声明变量的实现方案
完全可以通过Streams API直接处理,不需要提前声明变量接收,两种可行写法:
方案1:显式转型(临时解决)
对getter的返回值做显式泛型转型即可让编译器正确推导类型:
((List<Foo<Map<String, String>>>) my_data_structure.getListOfFoo()) .stream() .forEach(foo -> foo.getInnerMap().keySet());
该写法会保留未检查转换警告,和你赋值给变量的写法安全性一致,只是省略了中间变量。
方案2:修正数据结构的泛型定义(根源解决)
修改my_data_struct的泛型定义,消除不安全的类型转换,后续不需要任何额外处理即可直接链式调用:
public class MyDataStruct { // 成员变量泛型和getter返回值保持一致 private List<Foo<Map<String, String>>> foo; public List<Foo<Map<String, String>>> getListOfFoo() { return this.foo; } }
修正后直接调用即可正常编译:
my_data_structure.getListOfFoo().stream() .forEach(foo -> foo.getInnerMap().keySet());
内容的提问来源于stack exchange,提问作者sach
相关产品推荐
相关产品推荐

