自定义收集器无法编译

Custom collector not compile

我正在创建一个自定义收集器,但在编译时使用它时失败了。

 private static <T> Collector<T, ?, T> getFirstElement() {
    return Collectors.collectingAndThen(
        Collectors.toList(),
        list -> {
            if (list.size() == 0) {
                return null;
            }
            if (list.size() > 1) {
                log.info("There are more than 1 registry");
            }
            return list.get(0);
        }
    );
} 


String myString = "test";
Optional.of(myString)
   .map(myService::getFromDatabase)
   .collect(getFirstElement());

myService.getFromDatabase(字符串)return 项目列表。

编译时出现错误

cannot find symbol
[ERROR]   symbol:   method collect(java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.lang.Object>)
[ERROR]   location: class java.util.Optional<java.util.List<com.package.Item>>

为什么我会遇到这个错误?

正如我所说,您的收集器没有问题。

Optional 类型的对象无法访问方法 collect()。它有方法map()filter()stream(),但你不能在上面应用collect(),不要将可选与流混淆。

如果您需要验证必须作为参数传递给 getFromDatabase() 的字符串值不是 null,您可以使用 Objects.requireNonNull()(注意 Optional.of() 将在参数为 null).

的情况下抛出异常

假设 getFromDatabase() returns 一个列表 Item 对象,你可以这样写你的代码:

List<Item> items = 
    Stream.of(Objects.requireNonNull(myString, "error message")) // Stream<String>
          .map(myService::getFromDatabase)                       // Stream<List<Item>>
          .flatMap(List::stream)                                 // Stream<Item>
          .collect(getFirstElement());

如果您在使用 Optional.of() 时的意图是创建 Optinal<List<Item>> 类型的结果,那不是一个好主意(除了它不会编译).

可选,包含一个集合是一个反模式,因为它引入了不必要的冗余。空集合的作用相同,表示没有数据,因此不需要为此使用 optional。