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 个函数可以迭代:
keySet()
- 如果您只对键感兴趣
values()
- 如果您只对值感兴趣
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>
所以你的循环会遍历 HashMap
s,而不是 List
of HashMap
s所以应该是
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());
}
}
}
顺便说一句,在 Java 8 中,您的代码可以简化为
csvDict.entrySet().stream()
.flatMap(m -> m.getValue().stream())
.flatMap(m -> m.values().stream())
.forEach(System.out::println);
我有以下数据结构:
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 个函数可以迭代:
keySet()
- 如果您只对键感兴趣values()
- 如果您只对值感兴趣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>
所以你的循环会遍历 HashMap
s,而不是 List
of HashMap
s所以应该是
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());
}
}
}
顺便说一句,在 Java 8 中,您的代码可以简化为
csvDict.entrySet().stream()
.flatMap(m -> m.getValue().stream())
.flatMap(m -> m.values().stream())
.forEach(System.out::println);