如何遍历值为列表的LinkedHashMap

64

我有以下LinkedHashMap声明。

LinkedHashMap<String, ArrayList<String>> test1
我的观点是如何遍历这个哈希映射表。我想按照以下方式进行操作,对于每个键,获取相应的ArrayList并针对该键依次打印ArrayList的值。
我尝试了这个方法,但是get只返回字符串。
String key = iterator.next().toString();  
ArrayList<String> value = (ArrayList<String> )test1.get(key)

LinkedHashMap 用于保持顺序。问题和回答都没有提到顺序。请将 LinkedHashMap 替换为 HashMap。这非常令人困惑。 - apflieger
5个回答

159
for (Map.Entry<String, ArrayList<String>> entry : test1.entrySet()) {
    String key = entry.getKey();
    ArrayList<String> value = entry.getValue();
    // now work with key and value...
}

顺便提一下,你应该把变量声明为接口类型,比如Map<String, List<String>>


3
顺便说一下,我希望能够得到按插入顺序排列的列表,之前我使用哈希表但它打乱了顺序。 - P basak
4
我并不是说不要使用 LinkedHashMap,但最佳实践通常是声明类似于 Map<String, List<String>> map = new LinkedHashMap<String, List<String>> 这样的东西。 - matt b
1
@Pbasak,你只需在声明时使用接口类型。当你实例化map对象时,仍然会使用LinkedHashMap,这将确保插入顺序保持不变。这样,你就可以坚持自己的实现选择,同时在外部使用更通用的类型。 - Konrad Reiche
32
为什么使用 entrySet 返回的集合是有序的?我知道 LinkedHashMap 中的顺序是有保证的,但文档中说 set 的迭代器不保证顺序。 - Jonathan.
2
你为什么在声明中保留了ArrayList呢? - user985358
3
@Jonathan,好问题。迟做总比不做好:请参见https://dev59.com/YXA85IYBdhLWcg3wJf8Z#2924143 的答案。 - LarsH

15

我假设你的get语句中有一个错别字,应该是test1.get(key)。如果是这样,除非你在第一次放置映射时没有使用正确的类型,否则我不确定为什么它没有返回ArrayList。

这个应该能够工作:

// populate the map
Map<String, List<String>> test1 = new LinkedHashMap<String, List<String>>();
test1.put("key1", new ArrayList<String>());
test1.put("key2", new ArrayList<String>());

// loop over the set using an entry set
for( Map.Entry<String,List<String>> entry : test1.entrySet()){
  String key = entry.getKey();
  List<String>value = entry.getValue();
  // ...
}

或者您可以使用

// second alternative - loop over the keys and get the value per key
for( String key : test1.keySet() ){
  List<String>value = test1.get(key);
  // ...
}

除非你有很特别的理由使用实现方式来定义,否则在声明变量时(以及在泛型参数中)应该使用接口名称。


1
嗨,我使用LinkHashMap来保持元素的插入顺序。 - P basak
当创建实例时,您可以指定LinkedHashMap,但是在变量中使用接口名称可以使代码实现独立。也就是说,您可以轻松地在以后使用其他东西替换实现,而无需重新编写所有内容。请参见上面我的示例,其中使用接口作为变量声明和LinkedHashMap作为实现。 - Eric B.

12

在Java 8中:

Map<String, List<String>> test1 = new LinkedHashMap<String, List<String>>();
test1.forEach((key,value) -> {
    System.out.println(key + " -> " + value);
});

8
您可以使用entry set并迭代条目,这样您就可以直接访问键和值。
for (Entry<String, ArrayList<String>> entry : test1.entrySet()) {
     System.out.println(entry.getKey() + "/" + entry.getValue());
}

我尝试了这个方法,但只返回字符串

为什么你会这样认为呢?方法get返回了选择的泛型类型参数 E 的类型,例如ArrayList<String>


嘿,test1.entrySet()后面缺少一个括号,但由于编辑的长度小于6个字符,我无法进行修改,只是想为将来的用户指出这一点。 - FoundABetterName
1
我已经更新了,谢谢。 - Konrad Reiche

7
// iterate over the map
for(Entry<String, ArrayList<String>> entry : test1.entrySet()){
    // iterate over each entry
    for(String item : entry.getValue()){
        // print the map's key with each value in the ArrayList
        System.out.println(entry.getKey() + ": " + item);
    }
}

3
没想到,我在 C# 中使用了 foreach,这与此类似。 - P basak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接