Question

Say I have an interface:

public interface Foo { public void setId(int id); public int getId(); }

And objects that implement that interface:

public class Bar implements Foo { ... } ;

I wish to have a generic function that creates a Map in the form of Map<Id, Foo>.

I also wish for member variables like private Map<Integer, Bar> barMap to be set to the return value of this map.

The following:

private <T> Map<Integer, Foo> createMap(List<? extends Foo> foos) {
    Map<Integer, Foo> map = new LinkedHashMap<Integer,Foo>();
    for (Foo foo : foos) {
        map.put(foo.getId(), foo);
    }
    return map;
}

is legal.

But

List<Bar> barList = new ArrayList<Bar>();
barList.add(...);
...
Map<Integer, Bar> barMap = createMap(barList)

is illegal because I cannot convert from Map<Integer, Foo> to Map<Integer, Bar>. I also cannot cast the former to the latter.

How would I accomplish this?

Was it helpful?

Solution

You should be utilizing that T (the type parameter) -

private <T extends Foo> Map<Integer, T> createMap(List<T> foos) {
    Map<Integer, T> map = new LinkedHashMap<Integer, T>();
    for (T foo : foos) {

When you do that your generic method returns Map<Integer, Bar>, with the help of type inference, instead of Map<Integer, Foo>.

OTHER TIPS

try like this:

use ? extends Foo in the return type of the createMap method. ie your key should be Integer and value is something that extends Foo.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top