Search code examples
javainheritancepolymorphismcollectors

What's preventing me from returning a Map<String, List<String>> as a Map<String, Collection<String>>?


The following code won't compile:

  public static Map<String, Collection<String>> convert(Collection<Foo> foos) {
    return foos == null ? Maps.newHashMap()
                        : foos.stream().collect(
                            Collectors.groupingBy(
                                f -> f.getSomeEnum().name(),
                                Collectors.mapping(Foo::getVal, Collectors.toList())));
  }

Unless I change the return type to List:

  public static Map<String, List<String>> convert(Collection<Foo> foos) {

Normally I believe I should be able to, but maybe there is some ambiguity introduced by generics?

The exact error:

Incompatible types. Required Map<String, Collection<String>> but 'collect' was inferred to R: no instance(s) of type variable(s) A, A, A, A, A, A, D, K, R, R, T, T, T, U exist so that List<T> conforms to Collection<String>

I don't think the details are relevant but just in case:

Foo is like this:

public class Foo {
  private MyEnumType someEnum;
  private String val;
  public MyEnumType getSomeEnum();
  public String getVal();
}

and I am trying to convert a list of Foos to a map of Foos, vals grouped by someEnum.


Solution

  • Map<String, List<String>> is not a subtype of Map<String, Collection<String>>, see this for more.

    You can declare the return type as Map<String, ? extends Collection<String>>