学科分类
目录
Java基础

Map集合遍历

在程序开发中,经常需要取出Map中所有的键和值,那么如何遍历Map中所有的键值对呢?Map集合遍历的方式和单列集合Collection集合遍历的方式基本相同,主要有两种方式可以实现:第一种方式,可以使用Iterator迭代器遍历集合;第二种方式就是使用JDK 8提供的forEach(Consumer action)方法遍历集合。接下来,就以前面学习的HashMap集合为例来分别对这两种集合遍历方式进行详细讲解。

1.Iterator迭代器遍历Map集合

使用Iterator迭代器遍历Map集合,需要先将Map集合转换为Iterator接口对象,然后进行遍历,由于Map集合中元素是由键值对组成的,所以使用Iterator接口遍历Map集合时,会有两种将Map集合转换为Iterator接口对象再进行遍历的方法:keySet()方法和entrySet()方法。

其中,keySet()方法,需要先将Map集合中所有键对象转换为Set单列集合,接着将包含键对象的Set集合转换为Iterator接口对象,然后遍历Map集合中所有的键,再根据键获取相应的值。接下来就通过一个案例来演示先遍历Map集合中所有的键,再根据键获取相应的值的方式,如文件1所示。

文件1 Example15.java

 1    import java.util.*;
 2    public class Example15 {
 3        public static void main(String[] args) {
 4            Map map = new HashMap();            // 创建Map集合
 5            map.put("1", "Jack");               // 存储元素
 6            map.put("2", "Rose");
 7            map.put("3", "Lucy");
 8             System.out.println(map);
 9            Set keySet = map.keySet();         // 获取键的集合
 10            Iterator it = keySet.iterator();  // 迭代键的集合
 11            while (it.hasNext()) {
 12                Object key = it.next();
 13                Object value = map.get(key);  // 获取每个键所对应的值
 14                System.out.println(key + ":" + value);
 15            }
 16        }
 17    }

运行结果如图1所示。

图1 运行结果

文件1中,首先调用Map对象的KeySet()方法,获得存储Map集合中所有键的Set集合,然后通过Iterator迭代Set集合的每一个键元素,最后通过get(Objectkey)方法,根据键获取对应的值。

Map集合中的另外一种通过Iterator迭代器遍历集合的方式是使用entrySet()方法,该方法将原有Map集合中的键值对作为一个整体返回为Set集合,接着将包含键值对对象的Set集合转换为Iterator接口对象,然后获取集合中的所有的键值对映射关系,再从映射关系中取出键和值。接下来,将文件1中的第9~15行代码进行修改,通过使用entrySet()方法来进行Map集合遍历,修改后的代码示例如下所示:

import java.util.*;
public class Example15 {
    public static void main(String[] args) {
        Map map = new HashMap();    
        map.put("1", "Jack");       
        map.put("2", "Rose");
        map.put("3", "Lucy");
         System.out.println(map);
        Set entrySet = map.entrySet();
        Iterator it = entrySet.iterator();            // 获取Iterator对象
        while (it.hasNext()) {
              // 获取集合中键值对映射关系
            Map.Entry entry = (Map.Entry) (it.next());
            Object key = entry.getKey();              // 获取Entry中的键
            Object value = entry.getValue();         // 获取Entry中的值
            System.out.println(key + ":" + value);
        }
    }
}

再次运行文件1,运行结果如图2所示。

图2 运行结果

在上述修改的代码示例中,首先调用Map对象的entrySet()方法获得存储Map中所有键值映射的Set集合,这个集合中存放了Map.Entry类型的元素(Entry是Map接口内部类),每个Map.Entry对象代表Map中的一个键值对,然后迭代Set集合,获得每一个映射对象,并分别调用映射对象的getKey()和getValue()方法获取键和值。

2.JDK 8新方法遍历集合Map集合

与Collection集合遍历类似,在JDK 8中也根据Lambda表达式特性新增了一个forEach(BiConsumer action)方法来遍历Map集合,该方法所需要的参数也是一个函数式接口,因此可以使用Lambda表达式的书写形式来进行集合遍历。接下来通过一个案例来演示如何使用forEach(BiConsumer action)方法遍历Map集合,如文件2所示。

文件2 Example16.java

 1    import java.util.HashMap;
 2    import java.util.Map;
 3    public class Example16 {
 4        public static void main(String[] args) {
 5            Map map = new HashMap();     
 6            map.put("1", "Jack");        
 7            map.put("2", "Rose");
 8            map.put("3", "Lucy");
 9            System.out.println(map);
 10            // 使用JDK 8新增的forEach(BiConsumer action)方法遍历集合
 11            map.forEach((key,value) -> System.out.println(key + ":" + value));
 12        }
 13    }

运行结果如图3所示。

图3 运行结果

文件2中,使用了JDK 8中Map集合新增的forEach(BiConsumer action)方法对集合中的元素进行遍历,该方法传递的是一个Lambda表达式书写的函数式接口BiConsumer。forEach(BiConsumer action)方法在执行时,会自动遍历集合元素的键和值并将结果逐个传递给Lambda表达式的形参。

在Map集合中,除了以上两种主要的遍历方式外,还提供了一个values()方法,通过这个方法可以直接获取Map中存储所有值的Collection集合,接下来通过一个案例来演示,如文件3所示。

文件3 Example17.java

 1    import java.util.*;
 2    public class Example17 {
 3        public static void main(String[] args) {
 4            Map map = new HashMap();  
 5            map.put("1", "Jack");      
 6            map.put("2", "Rose");
 7            map.put("3", "Lucy");
 8            System.out.println(map);
 9            Collection values = map.values(); // 获取Map集合中value值集合对象
 10            // 遍历Map集合所有值对象V
 11            values.forEach(v -> System.out.println(v));
 12        }
 13    }

运行结果如图4所示。

图4 运行结果

在文件3中,通过调用Map的values()方法获取包含Map中所有值的Collection集合,然后迭代出集合中的每一个值。

多学一招:使用LinkedHashMap集合保证元素添加顺序

在前面小节介绍HashMap集合时,已经说明HashMap集合并不保证集合元素存入和取出的顺序。如果想让这两个顺序一致,可以使用Java中提供的LinkedHashMap类,它是HashMap的子类,和LinkedList一样也使用双向链表来维护内部元素的关系,使LinkedHashMap元素迭代的顺序与存入的顺序一致,接下来通过一个案例来学习一下LinkedHashMap的用法,如文件4所示。

文件4 Example18.java

 1    import java.util.*;
 2    public class Example18 {
 3        public static void main(String[] args) {
 4            Map map1 = new HashMap();         // 创建HashMap集合
 5            map1.put(2, "Rose");
 6            map1.put(1, "Jack"); 
 7            map1.put(3, "Lucy");
 8            map1.forEach((key,value) -> System.out.println(key + ":" + value));
 9            System.out.println("=====================");
 10            Map map2 = new LinkedHashMap(); // 创建LinkedHashMap集合
 11            map2.put(2, "Rose");
 12            map2.put(1, "Jack"); 
 13            map2.put(3, "Lucy");
 14            map2.forEach((key,value) -> System.out.println(key + ":" + value));
 15        }
 16    }

运行结果如图5所示。

图5 运行结果

在文件4中,分别创建了HashMap和LinkedHashMap两个集合,并按相同的顺序插入了相同的元素,然后使用forEach(BiConsumer action)方法将元素遍历取出。从运行结果可以看出,使用HashMap集合取出的元素并不能保证与存入元素顺序一致,而LinkedHashMap集合却可以保证存入和取出的一致性。

一般情况下,我们用的最多的是HashMap,在Map中插入、删除和定位元素,HashMap 是最好的选择。但如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列。

点击此处
隐藏目录