Java 中 Map 的常见遍历方法
1、Map 接口常见方法
方法签名 | 功能 |
---|---|
Set keySet() | 返回 map 中得 key 集合(Set) |
Collection values() | 返回 map 中的 value 集合(Collection) |
Set<Map.Entry<K, V>> entrySet() | 返回 map 对应的 Map.Entry 集合(set) |
V put(K key, V value) | 向 map 中添加键为 key,值为 value的元素(map中有key,则更新) |
V get(Object key) | 返回 map 中 key 对应的 value;如果 map 中不含 key,则返回 null |
default V getOrDefault(Objectl) key, V] defaultValue) | 返回 map 中 key 对应的 value;如果 map 中不含 key,则返回 defaultValue |
V remove(Object key) | 移除 map 中 key |
void clear() | 清空 map |
boolean isEmpty() | 判空(判断 map 中 size 是否为 0) |
boolean containsKey(Object key) | 查看 map 中是否包含 key |
boolean containsValue(Object value) | 查看 map 中是否包含 value |
注意:Map.Entry<K, V> 是 Map 的一个内部接口。接口中的内部接口默认是 public static 的。
-
HashMap 中使用了一个静态内部类 Node 实现了 Map.Entry<K, V> 接口
// jdk 1.8 HashMap 部分源码 public class HashMap extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; // key 是 final 修饰 V value; // value 和 key 不能用泛型类型在 Map.Etry<K, V> 接口定义 Node<K,V> next; Node(int hash, K key, V value, Node<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } public final K getKey() { return key; } public final V getValue() { return value; } ..... // 省略 } }
2、Map 的遍历方法
Map 的遍历方法主要有两大类方法:
- 先获取map 的 keySet,然后根据 key 获取对应的 value;
- 先获取 entrySet,然后直接从 entrySet 中获取 key 和 value。
其中,这两大类方法中,每一大类又都可以利用 foreach 循环 或者 迭代器 两种方法来遍历。
2.1 第一类方法
第一类方法:先获取map 的 keySet,然后取出 key 对应的 value
特点:
- 效率相对较低。(因为还要根据 key 从哈希表中查找对应的 value)
方法1
- 通过 foreach 遍历 map.keySet(),取出对应的 value
public static void printMap1(Map<Integer, String> map) {
if (map.size() == 0) {
System.out.println("the map is empty...");
return;
}
System.out.println("the elements in the map are like below...");
for (Integer key : map.keySet()) {
System.out.println(key + " : " + map.getOrDefault(key, ""));
}
}
方法2
- 通过 迭代器 迭代 map.keySet(),来取出对应的 value
public static void printMap2(Map<Integer, String> map) {
Set<Integer> keySet = map.keySet();
Iterator<Integer> it = keySet.iterator();
while (it.hasNext()) {
Integer cntKey = it.next();
System.out.println(cntKey + " : " + map.getOrDefault(cntKey, ""));
}
}
2.2 第二类方法
调用 map.entrySet()方法,获取 entrySet,然后直接从 entrySet 中获取 key 和 value。
特点:
- 效率较高(直接从 node 中获取key,value)
- 适用于大数据量 map 遍历
方法3
- 调用 map.entrySet(),然后使用 foreach 遍历 entrySet
public static void printMap3(Map<Integer, String> map) {
Set<Map.Entry<Integer, String>> entry = map.entrySet();
for (Map.Entry<Integer, String> it : entry) {
System.out.println(it.getKey() + " : " + it.getValue());
}
}
方法4
- 调用 map.entrySet(),然后使用 迭代器 遍历 entrySet
public static void printMap4(Map<Integer, String> map) {
Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
Iterator<Map.Entry<Integer, String>> it = entrySet.iterator();
while (it.hasNext()) {
Map.Entry<Integer, String> node = it.next();
System.out.println(node.getKey() + " : " + node.getValue());
}
}
第三、四类方法,通常为调试时使用
2.3 第三类方法
使用 forEach
方法,以及 lambda 表达式
map.forEach((k, v) -> System.out.println(k + " : " + v));
2.4 第四类方法
- 使用超类
AbstractMap
中的toString()
方法- AbstractMap 重写了 toString 方法,打印格式为 {key=value,…}
- 特点:
- 调试时,使用最为方便;
- 但是,只能打印固定格式(不过一般也不影响调式)
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "1ab");
map.put(3, "ad");
map.put(2, "adc");
System.out.println(map); // {1=1ab, 2=adc, 3=ad}