Подтвердить что ты не робот

Создание объекта коллекции с использованием Generics

Когда я пытаюсь создать объект, как показано ниже:

Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();

Что не так синтаксически, может ли кто-нибудь объяснить мне?

4b9b3361

Ответ 1

Дженерики не являются ко-вариантами. Вы можете использовать:

Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
^                                                                ^
--------------^------------------- becomes ------^               |
              -----------------must remain as type ---------------

В то время как Map на внешней левой стороне присваивания может "стать" a HashMap назначенным, то же самое нельзя применить к любым типам, которые отображаются как общие параметры.

Edit:

Как отмечено @Keppil, вы можете использовать ограниченный синтаксис подстановки:

Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();

Обратите внимание, что этот синтаксис не позволяет добавлять записи к карте, но полезен в качестве типа, который должен быть передан и из методов.

Некоторые ссылки:

Ответ 2

Аналогичная ошибка, например

List<Animal> list = new ArrayList<Dog>();

Параметрированный тип должен быть одного типа с обоих концов. Концепции наследования (IS-A) нет. Если вы все еще хотите использовать его, используйте подстановочный знак (?) С ключевым словом extend/super, который разрешен только по левой стороне знака равенства.

List<Animal> list = new ArrayList<Dog>(); // is not allowed

но

Animal[] animal = new Dog[10];  //is allowed
animal[0] = new Dog(); // is allowed

где он позже выйдет из строя и выдаст исключение, если кто-то попытается добавить объект Cat (extends Animal).

animal[1] = new Cat();  //compiles fine but throws java.lang.ArrayStoreException at Runtime.

Помните animal[1] или animal[index] держит reference для собаки. Таким образом, ссылочная переменная Dog может ссылаться на объект Dog object not Cat.

Итак, чтобы избежать такого сценария, JSL внесла такие изменения в список обобщений /Collection. Этот ответ также применим для вашего вопроса (Map).
Параметрированный тип должен быть одного типа с обоих концов.

List<Animal> list = new ArrayList<Animal>(); 

Ответ 3

Попробуйте это

Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();

Проще объяснить на более простом примере

Set<Number> set = new HashSet<Integer>();

не разрешено, потому что тогда вы можете добавить Double to HashSet of Integer

set.add(1.0)

Обратите внимание, что

Set<? extends Number> set = new HashSet<Integer>();

не позволяет добавить ничего, кроме null к набору. Но вы можете читать только цифры из него

Дополнительную информацию вы можете найти здесь http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

Ответ 4

вам нужно что-то вроде этого:

Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
myMap.put(1, new HashMap<String, Integer>());

Ответ 5

Map<String, Integer> не совпадает с HashMap<String, Integer>. Это проблема.

На самом деле HashMap реализует интерфейс карты. Поэтому он должен быть ? extends Map<String, Integer> с левой стороны

Ответ 6

Попробуйте следующее:

Map<Integer, HashMap<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();