Java的Collector到Optional<T>

3
使用Java流和泛型,我正在尝试创建一个Collector,如果流为空,则返回Optional.empty;如果流只有一个项目,则返回Optional;如果流有多个项目,则抛出异常。
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());

请问有人可以解释一下出了什么问题吗?
2个回答

3

这个答案已经告诉你如何正确声明方法。

然而,请注意你不需要这个特殊的收集器。你可以简单地使用

Collectors.reducing((first, second) -> {
    throw new CollectingException("More than one item found, "
        + "first: " + first + ", second: " + second);
})

这个已经可以完成你想要的工作了(参见Collectors.reducing(…)

  • 如果流是空的,将返回一个空的Optional
  • 如果流包含一个元素,将返回一个包含该元素的Optional
    请注意,这种方法不会先构建一个List,而是直接生成Optional
  • 如果有多个元素,将对约简函数进行求值,将它们约简为一个结果,在此处抛出预期的异常。
    请注意,这种方法不会浪费资源将所有意外的元素收集到一个List中,而是在遇到第二个元素时停止。

当您不想将此逻辑与其他收集器结合时,您根本不需要收集器,而是可以直接在流上使用reduce
List<Person> people = new ArrayList<>();

Optional<Person> john = people.stream()
    .filter(person -> "John".equals(person.getName()))
    .reduce((first, second) -> {
        throw new CollectingException("More than one item found, "
            + "first: " + first + ", second: " + second);
    });

与之相同

Optional<Person> john = people.stream()
    .filter(person -> "John".equals(person.getName()))
    .collect(Collectors.reducing((first, second) -> {
        throw new CollectingException("More than one item found, "
            + "first: " + first + ", second: " + second);
    }));


2
你的方法声明不正确,应该是:
public static <T, R extends Optional<T>> Collector<T, ?, R> toOptional() {

你可以直接使用:
public static <T> Collector<T, ?, Optional<T>> toOptional() {

换句话说,该方法需要直接返回一个类型为TOptional对象,而不是使用一个扩展Optional<T>的单独类型参数R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接