дженерики / наследование java во вложенном hashmap - PullRequest
3 голосов
/ 27 августа 2009

если у меня есть два хеш-карты, типа

HashMap<Integer, HashMap<Integer, Police>> time_id_police;  
HashMap<Integer, HashMap<Integer, Ambulance>> time_id_ambulance;

, где полиция и скорая помощь расширяют возможности спасения, как я могу получить метод, подобный

HashMap<Integer, HashMap<Integer, Rescue>> getRescue(){
   if (a) return time_id_police;
   else return time_id_ambulance;
}

ни это, ни изменение типа возврата на

HashMap<Integer, HashMap<Integer, ? extends Rescue>> 

похоже, работает.

Большое спасибо.

Ответы [ 2 ]

3 голосов
/ 27 августа 2009

Ясно, что HashMap<Integer, HashMap<Integer, Rescue>> неверно, потому что тогда значение можно заменить в time_id_police на HashMap<Integer, Ambulance>. Аналогичное можно сделать, если вы замените Rescue на ? extends Rescue.

Однако, использование ? extends дважды дает нам нечто, что не сломает систему типов.

HashMap<Integer, ? extends HashMap<Integer, ? extends Rescue>> getRescue() {

Большинство Java-программистов предпочитают использовать более общие Map в типах, а не в конкретной реализации.

Map<Integer, ? extends Map<Integer, ? extends Rescue>> getRescue() {

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

   return a ? time_id_police : time_id_ambulance;

Вы получаете немного более полезное сообщение об ошибке, так как компилятор определяет тип для вас:

R.java:18: incompatible types
found   : java.util.HashMap<java.lang.Integer,capture of ? extends java.util.HashMap<java.lang.Integer,? extends Rescue>>
required: java.util.HashMap<java.lang.Integer,java.util.HashMap<java.lang.Integer,Rescue>>
   return a ? time_id_police : time_id_ambulance;
        ^
1 error
0 голосов
/ 27 августа 2009

Измените ваши объявления time_id_police и time_id_ambulance на

HashMap<Integer, HashMap<Integer, Rescue>> time_id_police;
HashMap<Integer, HashMap<Integer, Rescue>> time_id_ambulance;

вы также можете объявить их как Map вместо HashMap. Таким образом, если вы когда-нибудь решите изменить реализацию Map, которую вы используете, вам нужно будет внести изменения только в одном месте (где вы создаете экземпляр своего объекта), а не чем во многих местах (где вы используете свой объект)

Map<Integer, Map<Integer, Rescue>> time_id_police = new HashMap<Integer, HashMap<Integer, Rescue>>();
...