0
public class People {
    class Family extends People {
    }
}

public class Together {
    private static ConcurrentMap<String, Collection<Family>> familyMap= new ConcurrentHashMap<String, Collection<Family>>();
    private static ConcurrentMap<String, ConcurrentMap<String, Collection<People>>> registry2 = new ConcurrentHashMap<String, ConcurrentMap<String, Collection<People>>>();

    static {
        registry2.put(Family.class.toString(), familyMap); 
    }
}

(I already tried changing the declaration of registry2 to having ? extends People

The error is: The method put(String, ConcurrentMap<String,Collection<People>>) in the type Map<String,ConcurrentMap<String,Collection<People>>> is not applicable for the arguments (String, ConcurrentMap<String,Collection<Family>>)

How can I put familyMap into the registry2 hashmap?

Stephen D
  • 2,836
  • 4
  • 27
  • 40
  • 4
    a `Collection` is not a `Collection`: http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p – assylias Jun 19 '13 at 20:58
  • I have tried that, it doesn't like that either. I understand that the heirarchy of polymorphism isn't the same with generics. Is there another way of putting familyMap into registry2? – Stephen D Jun 19 '13 at 21:01
  • 2
    Please, read the answers to your questions [here](http://stackoverflow.com/q/17196851/1237040) and [here](http://stackoverflow.com/q/17200675/1237040). Why are you making the same mistakes again and again? "Java Generics are NOT covariant!" – Ravi K Thapliyal Jun 19 '13 at 21:03

2 Answers2

3

This is not a Map problem : this is rather a Generics problem. You assume that a Collection<Family> is a subclass of Collection<People> because Family extends People, but this is not the case.

They are in fact totally different types, so the compiler complains that you are not passing arguments of the right type.


You can resolve the issue by making familyMap a Map that holds a collection of People objects. Your code will just happen to be putting Family objects into it, which is fine, because a Family IS a People.

But when getting the Family objects back out of the map you'll need to typecast them to a Family if you need to use specific Family functions, though there is some risk that down the road a People (and not a Family) object could sneak into it. You may want to consider a different design paradigm to mitigate that risk.

droozen
  • 176
  • 4
Olivier Croisier
  • 6,139
  • 25
  • 34
  • So if they don't extend similarily to how classes extend, is there no way of doing this? – Stephen D Jun 19 '13 at 21:03
  • @StephenD You may 1)replace `Collection>` and `Collection>` with `Family[]` and `People[]` because `Family[]` extends `People[]` or 2) replace `ConcurrentMap> familyMap` with `ConcurrentMap> familyMap`. – lifus Jun 19 '13 at 21:11
  • 2
    There is if you can change some of the types somewhere. For instance, you could use `ConcurrentMap>`. – Louis Wasserman Jun 19 '13 at 21:11
  • Yes, it's the best solution by far – lifus Jun 19 '13 at 21:13
  • If I put a `family` object casted as a `people` object, will I lose the distinct values of whatever the `family` object had within it's variables when I take it out of the `people` map and cast it back as a `family` object? – Stephen D Jun 20 '13 at 13:55
0

You're trying to put an incompatible type in because familyMap is a Collection<Family> and not a Collection<People> which you specify in registry2 (ConcurrentMap<String, Collection<People>>)

Dororo
  • 3,420
  • 2
  • 30
  • 46