Map 是我们在开发中常用的数据结构,它采用了键值对的数据存储方式,很适合用来缓存数据。
假设这么一个场景:我需要对缓存到 Map 中的数据做网络传输,或者本地持久化操作,应该怎么操作?
最粗暴的方法就是逐个读写,比如:
public void postData(Map<String, Object> map) {
Object value1 = map.get("key_1");
Object value2 = map.get("key_2");
...
JSONObject json = new JSONObject();
json.put("key_1", value1);
json.put("key_2", value2);
...
}
当 Map 中的数据非常多时,逐个读写的方式会显得格外臃肿。
在这种场景下,我们大概率不关心各个键值对的数据内容,其实可以直接采用遍历的方法。
Map 的遍历有多种实现方式:
Map.keySet()
public static void mapTraversal(Map<Object, Object> map) {
for (Object key : map.keySet()) {
Object value = map.get(key);
// Do something...
}
}
利用 foreach 循环,通过 Map 的 keySet() 遍历得出所有的 key,再利用 key 取得 value。
Map 的 keySet() 方法返回的是一个包含该 Map 中所有 key 的 Set 集合,因为 Set 具备迭代器,所以能够遍历取出对应的值。
Map.entrySet()
public void mapTraversal(Map<Object, Object> map) {
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
// Do something...
}
}
Map 中采用 Entry 内部类来表示一个映射项,映射项包含了 key 和 value,而 Map 的 entrySet() 方法返回的就是一个包含此映射项的 Set 集合,所以我们可以直接对其遍历。
Iterator
public static void mapTraversal(Map<Object, Object> map) {
Iterator<Map.Entry<Object, Object>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Object, Object> entry = it.next();
Object key = entry.getKey();
Object value = entry.getValue();
// Do something...
}
}
Iterator 对 Map 的遍历依然是使用 Map 的 entrySet() 方法取映射,套上 Iterator 似乎有点多此一举,但当你需要从 Map 中移除元素时,foreach 便无能为力了,而 Iterator 的 remove() 方法则能够帮你轻松实现。
Java 8 forEach() Lambda
public static void mapTraversal(Map<Object, Object> map) {
map.forEach((key, value) -> {
// Do something...
});
}
Java 8 提供了 Lambda 表达式支持,而 Map 也在 Java 8 加入了 forEach() 方法,语法看起来更简洁,可以同时拿到 key 和 value。
同时,由于 Collection 本身就继承自 Iterable,因此 keySet() 和 entrySet() 所获取到的 Set 集合便支持 Iterable 的 forEach() 方法。
