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()
方法。