JDK1.8下Set与Collection求交集出现inference variable RR类型不兼容报错
问题原因分析
- 泛型推断限制:JDK 1.8 对嵌套的 collector 泛型推断能力较弱,
Collectors.toSet()未显式指定类型时,编译器无法正确识别集合元素为VsatVlan类型,误推断为Set<Object>,导致 lambda 入参类型不匹配。 - 返回值类型冲突:
Set.size()返回值为int类型,你定义的接收变量intersectionCount是long类型,编译器在做泛型边界校验时出现类型冲突。 - 逻辑不符需求:你要求交集数量大于0,但原代码判断逻辑是只要集合大小不等于1就抛出异常,仅支持交集恰好为1的场景,和需求不符。
解决方案
方案1:直接简化实现(推荐)
不需要用 collectingAndThen 重载,直接用 stream.count() 统计即可,同时提前把 mobilityNsVlansList 转成 HashSet 把 contains 操作的时间复杂度从O(n)降到O(1),大幅提升性能:
SortedSet<VsatVlan> vsatVlans; // 先转HashSet优化查询性能 Set<Integer> mobilityVlanSet = new HashSet<>(mobilityNS.getVlanIds()); long intersectionCount = vsatVlans.stream() .map(VsatVlan::getVlanId) .filter(mobilityVlanSet::contains) .count(); // 校验交集数量大于0 if (intersectionCount <= 0) { throw new IllegalStateException("无符合要求的交集VLAN"); }
方案2:修复原有代码的类型问题
如果你需要保留原有 collectingAndThen 的写法,只要给 toSet() 显式指定泛型,同时对齐返回值类型即可:
long intersectionCount = vsatVlans.stream() .filter(vsatVlan -> mobilityNsVlansList.contains(vsatVlan.getVlanId())) .collect(Collectors.collectingAndThen( // 显式指定toSet的元素类型,解决泛型推断问题 Collectors.<VsatVlan>toSet(), set -> { // 这里判断逻辑按你实际需求调整,如果是要大于0就判断isEmpty if (set.isEmpty()) { throw new IllegalStateException(); } // int转long对齐返回值类型 return (long) set.size(); } ));
内容的提问来源于stack exchange,提问作者Alexei
相关产品推荐
相关产品推荐

