1
public class People {

    class Family extends People {

    }

}


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

    static {
        registry.put(Family.class.toString(), familyList); 
    }
}

Error message:

The method put(String, Collection<people>) in the type Map<String,Collection<people>> is not applicable for the arguments (String, Collection<family>)

Why can't I put familyList into registry? I figure that since family extendspeople that i should be able to place the sub types into the super type registry .

EDIT: The above is solved. My last part of the question involves a more complicated example using the same names:

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

Now 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>>)

Stephen D
  • 2,836
  • 4
  • 27
  • 40

3 Answers3

4

Because a Collection<family> is not a Collection<people>. Put another way: Java collections are not covariant.

Is there a way I could put family into the hashmap?

Declare it as a Collection<people>.

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
3

family is convertible to people, but Collection<family> is not convertible to Collection<people>.
Had it been convertible, you would have been able to unsafely add a different derived tyupe to the casted collection.

Instead, you can use a covariant view of the collection type:

ConcurrentMap<String, Collection<? extends people>>
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
1

Try this:

people.java

public class people {

    public class family extends people {

    }

    public static void main(String[] args) {
        together t = new together();
        System.out.println(together.registry);
    }

}

together.java

import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class together {
    private static Collection<people.family> familyList = new ArrayList<people.family>();
    public static ConcurrentMap<String, Collection<? extends people>> registry = new ConcurrentHashMap<String, Collection<? extends people>>();

    static {
        registry.put(people.family.class.toString(), familyList);
    }

}
axiopisty
  • 4,972
  • 8
  • 44
  • 73
  • Thanks for making this clear! I edited the question and will no doubt consult your answer for the first part of my question! – Stephen D Jun 19 '13 at 20:45
  • Great. I'm glad I could help. If this solution helped please select this as the correct answer. :) – axiopisty Jun 19 '13 at 20:47