2015-12-23 3 views
1
abstract class NodekaClass { 
    abstract HashMap getBuffs(); 
    abstract void setBuffs(HashMap<String, Boolean> buffs); 
} 

class Barbarian extends NodekaClass { 

    public HashMap <String, Boolean> buffs; 

    @Override 
    public HashMap getBuffs() { 
     return this.buffs; 
    } 
} 

Теперь вопрос .. если я пытаюсь сделать это:Перебор вызова метода из коллекции конкретизированных классов

 for (NodekaClass pet : activePets) { 
      for (String s : pet.getBuffs().keySet()) { 

      } 
     } 

Он говорит, что я должен бросить S в качестве родового объекта и выиграл» t позвольте мне получить доступ к любому из методов String.

Я мог бы сделать это приведение типа, как ...

 for (NodekaClass pet : activePets) { 
      for (Object o : pet.getBuffs().keySet()) { 
       if ("Test".equals((String) o)) 
       { 

       } 
      } 
     } 

Но это неуклюжее. Есть ли лучший способ итерации в этой ситуации?

+0

Что вы ожидаете, чтобы в вашем HashMap? Ключ всегда будет строкой? Что вы ожидаете от ценностей? – pmartin8

ответ

2

Изменение public HashMap getBuffs() в public HashMap<String, Boolean> getBuffs()

Как написано ваш метод возвращает простую HashMap и хочет вернуть родовую версию, один с общей декларацией на месте. Поймите, что generics предназначены только для компилятора, а не для JVM, где они почти не существуют, и поэтому, если ваш метод не объявляет о его возврате, компилятор будет знать только, что метод возвращает простой HashMap.

+0

Хорошо, я возвращаю общий «HashMap», а не мой конкретный контейнер? –

+1

@IsaacCroas: вы возвращаете простой «HashMap» и хотите вернуть общую версию, в которой есть общая декларация. Поймите, что generics предназначены только для компилятора, а не для JVM, где они почти не существуют, и поэтому, если ваш метод не объявляет о его возврате, компилятор будет знать только, что метод возвращает простой HashMap. –

0

Почему бы не сделать это таким образом:

@Override 
public HashMap<String,Boolean> getBuffs() { 
    return this.buffs; 
} 

Тогда ваш первый способ будет работать без боли.

0

На самом деле, вам не нужно бросить: метод equals() принимает параметры типа Object, поэтому этот тест:

if ("Test".equals(o)) 

будет работать правильно и безопасно, то это будет true если o является строка "Test" (false в противном случае) и не будет исключать какие-либо исключения независимо от того, какой класс o (включая null).

0

Если ключ карты являются строки и значения Булевы вы можете delare это так:

abstract class NodekaClass { 
abstract Map<String, Boolean> getBuffs(); 
abstract void setBuffs(Map<String, Boolean> buffs); 

}

class Barbarian extends NodekaClass { 

public Map<String, Boolean> buffs; 

@Override 
public Map<String, Boolean>getBuffs() { 
    return this.buffs; 
} 
Смежные вопросы