You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Function<? extends T, Long>无法适配Java Stream的map方法?如何修复?

代码错误修复方案

问题分析

原代码第12行map(idGetter)出现类型不匹配错误,核心原因是:

  • children的类型为List<? extends T>,其stream元素是任意T的子类(记为U)
  • 传入的idGetter类型是Function<? extends T, Long>,表示该函数仅能接受**某个特定T的子类(记为V)**作为输入
  • 编译器无法保证U和V是兼容类型,因此判定类型不匹配。

修复方案

推荐两种类型安全的修复方式:

方式1:将Function参数类型改为Function<T, Long>

修改方法的第三个参数声明,利用子类向上转型为父类的特性,让List<? extends T>中的元素能安全传入函数:

public <T> List<Long> leafIds(Map<Long, ? extends List<? extends T>> childrenMap, Long parentId, Function<T, Long> idGetter) {
    if (!childrenMap.containsKey(parentId)) {
        return Collections.singletonList(parentId);
    }
    List<Long> result = new ArrayList<>();
    List<Long> childrenIds = new ArrayList<>();
    childrenIds.add(parentId);
    for (int i = 0; i < childrenIds.size(); i++) {
        Long childId = childrenIds.get(i);
        List<? extends T> children = childrenMap.get(childId);
        if (CollectionUtils.isNotEmpty(children)) {
            childrenIds.addAll(children.stream().filter(Objects::nonNull).map(idGetter).collect(Collectors.toList()));
            continue;
        }
        result.add(childId);

    }
    return result;
}

方式2:将Function参数类型改为Function<? super T, Long>

如果需要更宽泛的函数输入范围,可将参数改为支持T或T的父类作为输入的函数,自然兼容所有T的子类元素:

public <T> List<Long> leafIds(Map<Long, ? extends List<? extends T>> childrenMap, Long parentId, Function<? super T, Long> idGetter) {
    // 内部代码无需修改,保持原逻辑即可
}

不推荐的方式(存在类型安全风险)

不建议用强制类型转换绕过编译检查,比如:

childrenIds.addAll(children.stream().filter(Objects::nonNull).map(t -> idGetter.apply((T) t)).collect(Collectors.toList()));

这种方式可能在运行时抛出ClassCastException,当children中的元素实际类型与idGetter预期输入类型不匹配时会出错。

内容的提问来源于stack exchange,提问作者kai kang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:25:21