Java自定义Collector转Optional<T>时泛型报错问题求助
自定义Collector泛型错误排查
问题场景
想要实现一个Java Stream Collector,满足以下逻辑:
- 流为空时返回
Optional.empty() - 仅含一个元素时返回
Optional<T> - 元素数量多于一个时抛出异常
编写的原代码如下:
public static <T, R extends Optional<T>> Collector<T, ?, R> toOptional() { return Collectors.collectingAndThen( Collectors.toList(), list -> { if (list.size() > 1) { throw new CollectingException("More than one item found in: " + list); } if (list.size() == 1) { return Optional.of(list.get(0)); } return Optional.empty(); } ); }
编译时出现错误:
Required type: Collector<T,?,R> Provided: Collector<Object,Object,Object> no instance(s) of type variable(s) T exist so that Optional<T> conforms to R inference variable RR has incompatible bounds: equality constraints: R lower bounds: Optional<T1868063>
期望用法示例:
List<Person> people = new ArrayList<>(); Optional<Person> john = people.stream().filter(person->"John".equals(person.getName())).collect(toOptional());
错误原因
- 多余且无效的泛型约束:原方法声明的
<T, R extends Optional<T>>完全没必要,而且Optional是final类,根本无法被继承,R extends Optional<T>这个约束本身就不成立,编译器找不到符合条件的R类型。 - 类型推断不匹配:
Collectors.collectingAndThen返回的是Collector<T, ?, Optional<T>>,但方法声明要求返回Collector<T, ?, R>,泛型参数R的存在导致编译器无法正确推断类型,最终出现类型不兼容的错误。
修正后的代码
去掉多余的泛型参数R,直接将方法返回类型定义为Collector<T, ?, Optional<T>>:
public static <T> Collector<T, ?, Optional<T>> toOptional() { return Collectors.collectingAndThen( Collectors.toList(), list -> { if (list.size() > 1) { throw new CollectingException("More than one item found in: " + list); } return list.stream().findFirst(); } ); }
(注:可以直接用list.stream().findFirst()简化原有的判断逻辑,效果完全一致)
修正后,期望用法可以正常编译运行,完全符合需求逻辑。
内容的提问来源于stack exchange,提问作者Michal Krasny
相关产品推荐
相关产品推荐

