使用Java 8 Stream遍历嵌套对象列表转Map报类型不匹配错误
报错原因
你的代码错误出在flatMap()的使用逻辑上:
flatMap()方法要求传入的函数返回值必须是Stream类型,作用是把多层嵌套的流合并拍平为单层流- 你当前在
flatMap的lambda内部直接对每个工单类型的自定义字段流执行了collect收集操作,返回的是Map对象而非Stream,编译器无法将Map识别为流元素,最终把整个流的泛型推断为Object,自然无法将Stream<Object>直接赋值给Map类型变量,触发编译错误。
修正后的代码
先通过flatMap把所有IssueTypeDto下嵌套的CustomFieldDto全部拍平成一个连续的CustomFieldDto流,再统一执行收集为Map的操作即可:
Map<String, TypeDto> customFieldTypeMap = issueTypes.stream() // 拍平嵌套结构:将每个IssueType下的自定义字段列表转为流后合并 .flatMap(issueType -> issueType.getCustomFields().stream()) // 对所有拍平后的自定义字段收集为Map,key为字段id,value为字段类型 .collect(Collectors.toMap( CustomFieldDto::getId, CustomFieldDto::getType ));
边界场景适配
- 如果业务场景下可能存在不同自定义字段id重复的情况,上述代码会抛出
IllegalStateException(toMap默认不允许重复键),需要传入第三个参数指定重复键的合并规则,比如新值覆盖旧值:
Map<String, TypeDto> customFieldTypeMap = issueTypes.stream() .flatMap(issueType -> issueType.getCustomFields().stream()) .collect(Collectors.toMap( CustomFieldDto::getId, CustomFieldDto::getType, (oldVal, newVal) -> newVal // 重复id时保留后遍历到的字段类型 ));
- 如果接口返回的
customFields字段可能为null(而非空列表),可以加空判断避免空指针:
Map<String, TypeDto> customFieldTypeMap = issueTypes.stream() .flatMap(issueType -> Optional.ofNullable(issueType.getCustomFields()) .map(List::stream) .orElse(Stream.empty())) .collect(Collectors.toMap( CustomFieldDto::getId, CustomFieldDto::getType, (oldVal, newVal) -> newVal ));
内容的提问来源于stack exchange,提问作者Sachin HR
相关产品推荐
相关产品推荐

