2015-07-23 2 views
0

Я получил следующую структуру данных:возвращает HashMap в ПолучитьЗначение Объект

CFU66=[{Bild1=CFU6606}, {Bild2=CFU6603}, {Bild3=CFU6605}, {Bild4=CFU6601}, {Bild5=CFU6602}] 

Состав: Hashmap_1(String Key, List(Hashmap_2(String Key, String Value)))

Я пытаюсь получить доступ к значениям из Hashmap_2:

// for each Hashmap_1 entry 
for (Map.Entry<String, List> csvDictEntry : csvDict.entrySet()) { 
    // for each List in entry.getValue 
    for (List<HashMap> hashList : csvDictEntry.getValue()) { 
     // for each Hashmap_2 in List 
     for (HashMap<String, String> hashListDict : hashList) { 
     // for each entry in Hashmap_2 print Value 
     for (Map.Entry<String, String> entry :hashListDict.entrySet()){ 
      System.out.println(entry.getValue()); 
     } 
     } 
    } 
} 

Компилятор дает сообщение, что csvDictEntry.getValue() во втором for-loop возвращает Object вместо Hashmap. Зачем?

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

+0

Что вы пытаетесь сделать? распечатать все значения в 'hashmap_2'? – Karthik

+0

На самом деле я хочу дать значения из 'hashmap_2' JavaBean с сеттерами и getters. – jwi

+1

Поскольку тип 'csvDictEntry' является' Map.Entry ', а не' Map.Entry > '. Вы, вероятно, предупреждали о компиляторе типа «Список». – Pshemo

ответ

1

основе

for (Map.Entry<String, List> csvDictEntry : csvDict.entrySet()) { 

Я предполагаю, что тип csvDict является

Map<String, List> csvDict = ...; 

, где на основе вашего примера данных CFU66=[{Bild1=CFU6606}, {Bild2=CFU6603}, {Bild3=CFU6605}, {Bild4=CFU6601}, {Bild5=CFU6602}]

должно быть

Map<String, List<Map<String,String>>> csvDict = ...; 

Проблема с ссылочного типа является то, что List является сырым типа, что означает, что его фактический тип неизвестен (он может хранить любые объекты), так Object имеет тип, который компилятор предполагает, когда вы пытаетесь перебирать такие список так, когда обычно мы ожидали бы

for (Type t : List<Type>) 

для сырого типа мы получаем

for (Object o : rawList) 

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

for (List<HashMap> hashList : csvDictEntry.getValue()) 

не будет компилироваться, так getValue() возвращает List<HashMap> так что ваш цикл будет перебирать HashMap с, не List из HashMap с поэтому он должен быть

for (HashMap hashList : csvDictEntry.getValue()) 

Подсказка: старайтесь избегать конкретных типов в дженериках, используйте родительский тип, если это возможно, например интерфейс или абстрактный тип. Это позволит вам позже легко изменять фактический тип, например от HashMap до LinkedHashMap.

Так что ваша итерация должна выглядеть

for (Map.Entry<String, List<Map<String, String>>> csvDictEntry : csvDict.entrySet()) { 
    // for each Map in List stored as value 
    for (Map<String, String> hashListDict : csvDictEntry.getValue()) { 
     // for each entry in hmap_2 print Value 
     for (Map.Entry<String, String> entry : hashListDict.entrySet()) { 
      System.out.println(entry.getValue()); 
     } 
    } 
} 

DEMO


BTW в Java 8 ваш код может быть упрощенно

csvDict.entrySet().stream() 
    .flatMap(m -> m.getValue().stream()) 
    .flatMap(m -> m.values().stream()) 
    .forEach(System.out::println); 
+0

Ваше решение выглядит хорошо для меня, но компилятор говорит: 'Ошибка: (29, 90) java: несовместимые типы требуется: java.util.Map.Entry >> найдено: java.util.Map.Entry ' – jwi

+0

@jwi Каков код в строке, который вызывает эту ошибку? – Pshemo

+0

Получил! Я пропустил, чтобы поставить 'csvDict >>' также в объявлении метода как аргумент. Во всяком случае, ваш ответ был очень полезным. Спасибо и приветствует! – jwi

4

этого

for (Map.Entry<String, List> csvDictEntry : csvDict.entrySet()) { 

должен быть

for (Map.Entry<String, List<Map<String, String>>> csvDictEntry : csvDict.entrySet()) { 
+0

Лучше также указать параметры типа для HashMap, я думаю. – Puce

+0

да, хороший звонок. – Styl

0

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

Декларация набора ввода является:

Set<Map.Entry<K,V>> <-------  entrySet() 
Returns a Set view of the mappings contained in this map. 

так что вы должны пересмотреть chaging ваш первый ибо:

for (Map.Entry<String, List<HashMap>> csvDictEntry : csvDict.entrySet()) { 
2

Просто напишите все типы

Map<String, List<HashMap<String, String>>> csvDict = null; 

    for (Map.Entry<String, List<HashMap<String, String>>> csvDictEntry : csvDict.entrySet()) { 
     // for each List in entry.getValue 
     for (HashMap<String, String> hashList : csvDictEntry.getValue()) { 
      // for each Hashmap_2 in List 
      for (Map.Entry<String, String> entry : hashList.entrySet()) { 
       System.out.println(entry.getValue()); 
      } 
     } 
    } 

А также вы есть дополнительные for петля.

+0

@Puce Какой цикл? – talex

1

Как указано другими, вы забыли использовать <> после «Список» в вашей первой строке кода. Поэтому компилятор не знает, какие элементы находятся в этих списках. Также вы делаете его излишне сложным, итерации по entrySet, когда вас интересуют только значения.

Карта имеет 3 функции перебирать:

  1. keySet() - если вы заинтересованы только в ключах
  2. values() - если вы заинтересованы только в значениях
  3. entrySet() - если вы» заинтересованные как в

Так что в вашем случае ...

for (Map<String,String> map : csvDict.values()) { 
    for (String value : map.values()) { 
     System.out.println(value); 
    } 
} 
Смежные вопросы