Hashmap 的 getValue returns 对象

Hashmap's getValue returns Object

我有以下数据结构:

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());
         }
      }
   }
}

编译器给出消息,即第二个 for 循环 returns 中的 csvDictEntry.getValue()Object 而不是 Hashmap。为什么?

不过,我对 Java 还是个新手,我相信有更方便的方法可以做到这一点。

这个

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

应该是

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

您的问题是第一个,因为您目前正在检索通用列表,而不是特定列表。

条目集声明为:

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

所以你应该重新考虑改变你的第一个:

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

只写你所有的类型

    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 循环。

正如其他人所指出的,您忘记在第一行代码的 'List' 之后使用 <>。因此,编译器不知道这些列表中有哪些元素。 此外,当您只对值感兴趣时,通过遍历 entrySet 会使它变得不必要的复杂。

Map 有 3 个函数可以迭代:

  1. keySet() - 如果您只对键感兴趣
  2. values() - 如果您只对值感兴趣
  3. entrySet() - 如果您对两者都感兴趣

所以在你的情况下...

for (Map<String,String> map : csvDict.values()) {
    for (String value : map.values()) {
        System.out.println(value);
    }
}

基于

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() returns List<HashMap> 所以你的循环会遍历 HashMaps,而不是 List of HashMaps所以应该是

for (HashMap hashList : csvDictEntry.getValue())

提示:尽量避免泛型中的具体类型,尽可能使用父类型,如接口或抽象类型。这将允许您稍后轻松更改实际类型,例如从 HashMapLinkedHashMap.

所以你的迭代应该看起来像

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


顺便说一句,在 Java 8 中,您的代码可以简化为

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