2
public interface A {
    int getA();
}

public class MyObj implements A {
    public int getA(){
        return 1;
    }
}

If have a Map : Map<? extends A, String> aMap = new HashMap<>();

How can I add an MyObj to this aMap ? Or how should be the class MyObj so that it can work in this map

Cœur
  • 37,241
  • 25
  • 195
  • 267
Elie Daher
  • 271
  • 1
  • 4
  • 13

2 Answers2

6

How can i add an MyObj to this aMap ?

You can't, because of the upper bound on the key type.

The reason is that ? extends A could be MyOtherObj implements A. In this case, it would be type-unsafe to be able to put a key of type MyObj into the map:

Map<MyOtherObj, String> anotherMap = new HashMap<>();

Map<? extends A, String> aMap = anotherMap;
aMap.put(new MyObj(), "");  // Can't do this; but if you could...

MyOtherObj obj = anotherMap.keySet().iterator().next();  // ClassCastException!

Remember the acronym PECS (see this question for a lot more detail):

  • Producer extends
  • Consumer super

In other words, Map<? extends A, String> can only be used to produce instances of A, it can't consume/accept instances of A.

For example, you can iterate the keys ("producing" the keys):

for (A a : aMap.keySet()) { ... }

The map can only "consume" a literal null:

aMap.put(null, "");

because null can be cast to any type without exception. But there's not much use in a map which only has a single key - you may as well just store the value directly.

The only way to do this type-safely is to put the instance of MyObj into the map via a reference which you know accepts MyObj instances:

Map<MyObj, String> safeMap = new HashMap<>();
safeMap.put(new MyObj(), "");

Map<? extends A, String> aMap = safeMap;

or

Map<A, String> safeMap = new HashMap<>();
safeMap.put(new MyObj(), "");

Map<? extends A, String> aMap = safeMap;

But you should consider not having the wildcard-typed map at all; Map<MyObj, String> or Map<A, String> is easier.

Community
  • 1
  • 1
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
2

This isn't possible. Your compiler won't allow it.

You have to change your Map to:

Map<A, String> aMap = new HashMap<>();

After this you can use put to add an element to it:

aMap.put(new MyObj(), "myObject");
FrisoD
  • 514
  • 4
  • 4