我正在编写一种方法,该方法旨在递归地搜索嵌套集合中的值,然后返回包含该值的集合:

@SuppressWarnings("unchecked")
public static <E,
               R extends Collection<? extends E>> Optional<R> findRecursively(Collection<?> collection, E element)
                  throws ClassCastException {
   if (collection.isEmpty())
      return Optional.ofNullable(null);

   boolean nested = collection.stream()
                              .allMatch(e -> isSubclass(e.getClass(), Collection.class));
   for (Object c : collection) {
      R result;

      if (nested) {
         Optional<R> recursiveResult = findRecursively((Collection<?>) c, element);
         result = recursiveResult.orElse(null);
      } else {
         result = c.equals(element) ? (R) collection : null;
      }

      if (result != null)
         return Optional.of(result);
   }
   return Optional.ofNullable(null);
}

这很好用,但是当我使用该方法时,如果不首先将其提供给变量,就不能直接使用返回的Optional:
Collection<String> collection = null;
Set<String> set = Util.findRecursively(collection, "")
                      .orElseThrow(RuntimeException::new);

在那种情况下,编译器无法知道方法的返回类型。
我不知道有什么好的办法可以使它工作。

我想出了两种其他方法,它们也不是很好:
  • 我添加了一个带有return-type类型的参数,应该像这样返回:
    public static <E,
                   R extends Collection<E>> Optional<R> findRecursively(Collection<?> collection,
                                                                        E element,
                                                                        Class<R> returnType) {...
    

    但是我不喜欢这样,因为附加参数(实际上)是不必要的,并且使该方法不易理解。
  • 我只返回集合对象,而不是可选的。但是在那种情况下,我无法直接通过调用它来创建Optional,例如:
    Collection<String> collection = null;
    Set<String> set = Optional.ofNullable(Util.findRecursively(collection, ""))
                              .orElseThrow(RuntimeException::new);
    

    因为在这里,编译器仍然不知道返回类型,因此无法将类型参数推导给of()方法。

  • 有人对这个问题有好的解决方案的想法吗?或建议您去哪儿?

    最佳答案

    您可以在同一行中声明具体类型,而无需声明var:

    Util.<Collection, String, Set<String>>findRecursively(collection, "")...
    

    09-17 19:55
    查看更多