При попытке создать объект, как показано ниже:Коллекция с помощью Generics
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Что плохого синтаксически, может ли один объяснить мне?
При попытке создать объект, как показано ниже:Коллекция с помощью Generics
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Что плохого синтаксически, может ли один объяснить мне?
Это похоже ошибка, как
List<Animal> list = new ArrayList<Dog>();
Parameterized типа должны быть одного типа на обоих концах. Концепции наследования (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
(расширяет животных) объекта.
animal[1] = new Cat(); //compiles fine but throws java.lang.ArrayStoreException at Runtime.
Запомнить animal[1]
или animal[index]
держит reference
собак. Таким образом, Dog
ссылочная переменная может ссылаться на Dog
объект не Cat
объект.
Так, чтобы избежать такого сценария, JSL внесла такие изменения в список обобщений/Collection. Этот ответ также применим для вашего вопроса (Map
).
Параметрированный тип должен быть одного типа с обоих концов.
List<Animal> list = new ArrayList<Animal>();
Дженерики не являются ко-вариантами. Вы можете использовать:
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
^ ^
--------------^------------------- becomes ------^ |
-----------------must remain as type ---------------
Хотя Map
на внешней левой части задания может «стать» HashMap
как назначено, то же самое не может быть применен к любым типам, которые появляются в качестве родовых параметров.
Edit:
Как отметил @Keppil, вы можете использовать ограниченный синтаксис подстановки:
Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Обратите внимание, что этот синтаксис не позволит записи, которые будут добавлены к карте, но полезно как тип, который должен быть передан методам и из них.
Некоторые ссылки:
Попробуйте это:
Map<Integer, HashMap<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
вам нужно что-то вроде т его:
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
myMap.put(1, new HashMap<String, Integer>());
Попробуйте
Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Это проще для объяснения на более простом примере
Set<Number> set = new HashSet<Integer>();
не допускается, потому что тогда вы могли бы добавить Double к HashSet из Целые
set.add(1.0)
Записка th в
Set<? extends Number> set = new HashSet<Integer>();
не позволяет добавить что-нибудь, но null
к набору. Но вы можете только читать номера из него
Вы можете найти более подробную информацию здесь http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
Map<String, Integer>
не такой же, как HashMap<String, Integer>
. Это проблема.
На самом деле HashMap реализует интерфейс карты. Так что это должно быть ? extends Map<String, Integer>
с левой стороны
Вы также можете использовать 'Map> myMap = new HashMap >(); ' –
Keppil
@Reimeus мне будет полезно другое объяснение .. –