Map<Person, List<Dog>> not compatible with Map<Person, List<? extends Dog>> Map<Person, List<? extends Dog>> . In this case, it is expected that the map value type will be List<? extends Dog> List<? extends Dog> , not something that can be converted to the same thing. But if you used the parameter Map<Person, ? extends List<? extends Dog>> Map<Person, ? extends List<? extends Dog>> Map<Person, ? extends List<? extends Dog>> for f , it will work.
Here is a simple example that includes more basic types:
Map<String, List<?>> foo = new HashMap<String, List<Object>>();
OP asks why this is happening. The simple answer is that type parameters are invariant, not covariant. That is, the specified type Map<String, List<?>> , the type of the map value must be exactly List<?> , And not something similar to it. What for? Imagine if covariant types are allowed:
Map<String, List<A>> foo = new HashMap<>(); Map<String, List<?>> bar = foo;
Unfortunately, a violation of foo.get("baz").get(0) as A violated.
Now suppose we do it right:
Map<String, List<A>> foo = new HashMap<>(); Map<String, ? extends List<?>> bar = foo; List<B> baz = new ArrayList<>(); baz.add(new B()); bar.put("baz", baz);
There, the compiler tried to put an incompatible list in foo (via the alias bar ). That is why it is required ? extends ? extends