如何使用自定义List Supplier实现收集操作并解决泛型编译错误
编译错误核心原因
你的代码存在4个直接触发编译报错的问题:
- 入参使用原始类型
List,完全丢失源列表的元素泛型信息,编译器无法建立源元素、映射函数、目标集合之间的类型匹配关系 - 泛型参数
P的上界定义为List<? extends Serializable>,使用了上限通配符导致集合元素类型为未知的Serializable子类,编译器无法确认映射后的结果类型R能被该集合接收,自然报类型无法转换的错误 - 流操作写法错误:原生
List接口没有map方法,且l -> mapper的写法没有将流中元素传入映射函数执行,逻辑本身不成立 - 泛型参数之间没有绑定关联:映射输出类型R和结果集合P的元素类型完全没有约束关系,类型校验链断裂。
可直接运行的泛型实现
你只需要补全泛型参数的绑定关系,修正流操作逻辑即可,不需要绕额外的Supplier封装:
import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; protected <T, R, P extends List<R>> void mapper(Function<? super T, ? extends R> mapper, List<T> sourceList, P resultList) { sourceList.stream() .map(mapper) .collect(Collectors.toCollection(() -> resultList)); }
实现说明
- 把源列表的泛型明确为
List<T>,不再使用原始类型,让编译器能识别源元素类型T,和映射函数的入参约束? super T匹配 - 把泛型参数P的上界从
List<? extends Serializable>调整为List<R>,强制要求传入的结果集合必须能存储映射输出的R类型元素,打通类型校验链路 - 如果你要求结果元素必须实现Serializable,只需要给R加上上界约束即可,泛型签名改成
<T, R extends Serializable, P extends List<R>>,完全兼容你的业务约束 - 通过
Collectors.toCollection指定收集目标为你传入的自定义列表实例,不管你传入的是继承自ArrayList<CustomClass>的CustomClassList,还是其他自定义List实现,只要元素类型和映射结果类型匹配就能正常收集结果。
调用示例
假设你的CustomClassList定义为class CustomClassList extends ArrayList<CustomClass>,映射逻辑是把源对象转成CustomClass:
// 初始化自定义结果列表 CustomClassList resultList = new CustomClassList(); // 传入源列表、映射规则、自定义结果实例即可 mapper(SourceObj::toCustomClass, sourceDataList, resultList); // 执行完成后转换后的所有结果都会被收集到传入的resultList中
内容的提问来源于stack exchange,提问作者bluelurker
相关产品推荐
相关产品推荐

