Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My method returning an Optional cannot be used in a functional-like way

I am writing a method, that is intended to search a nested collection recursively for a value and return the collection, which contains that value:

@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);
}

This works fine, but when I use that method I cannot work with the returned Optional direktly without giving it to a variable first like this:

Collection<String> collection = null;
Set<String> set = Util.findRecursively(collection, "")
                      .orElseThrow(RuntimeException::new);

In that case the compiler cannot know the return-type of the method. I don't know any good possibility to make it work.

I figured out 2 other ways, that are not very nice either:

  1. I add a parameter with type of the return-type that should be returned like:

    public static <E,
                   R extends Collection<E>> Optional<R> findRecursively(Collection<?> collection,
                                                                        E element,
                                                                        Class<R> returnType) {...
    

    But I don't like this, because the additional parameter is (actually) unnecessary and makes the method less easily understandable.

  2. Instead of an Optional I return just the collection-object. But in that case I cannot create an Optional directly with calling it either like:

    Collection<String> collection = null;
    Set<String> set = Optional.ofNullable(Util.findRecursively(collection, ""))
                              .orElseThrow(RuntimeException::new);
    

    Because here again the compiler doesn't know the return-type and cannot infer the type-arguments to the of() method.

Does anybody have any idea of a nice solution for this issue? Or an advise which way to go here?

like image 453
David Avatar asked Nov 17 '25 11:11

David


1 Answers

you can state the concrete types in the same line without declaring a var:

Util.<Collection, String, Set<String>>findRecursively(collection, "")...
like image 117
aviad Avatar answered Nov 19 '25 03:11

aviad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!