0

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?

Matthew Moisen
  • 16,701
  • 27
  • 128
  • 231

2 Answers2

2

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>.

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
0

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.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Balaji Krishnan
  • 1,007
  • 3
  • 12
  • 29