做自然语言处理写了挺久的 Python
,经常要处理数据。用 Python
中的处理数据真的挺爽的 🫣,我平常都喜欢把各种数据都往 dict
(也就是 Java
中的 map
) 和 json
上转,用 Python
处理这个各种方便。 最近再写 Java
就经常“手残”,所以总结一下 Java
中处理 Map
。
⭐️ 遍历方式
Java 遍历 Map,要么就是遍历它的 Map.Entry<K,V> <- entrySet()
,要么就是遍历它的 key KeySet <- keySet()
。主要可以用下面四种方式遍历:
Iterator
ForEach
Lambda
Stream
除非特殊需要,尽量使用后 3 种遍历方式,使用 Iterator
可能更容易造成一些错误(Effective Java - 58:for-each
优先于 for
循环)。
在一些 for-each
不能胜任的地方,其实也有很对内置方法能够完成操作,不仅更加直观,而且非常易用。比如删除操作:Collection#removeIf()
Java 1.8+
。
ForEach
EntrySet
1
2
3
4
5
6
7
8
| Set<Map.Entry<K, V>> entrySet();
// ---
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}
|
KeySet
1
2
3
4
5
6
7
| Set<K> keySet();
// ---
for (String key : map.keySet()) {
String value = map.get(key);
}
|
Lambda
1
2
3
4
5
6
7
8
9
10
11
12
| public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {
@Override
public void forEach(Biconsumer<? super K, ? super V> action) {
}
}
// ---
map.forEach((key, value) -> {
// key
// value
})
|
Stream
Steram
1
2
3
4
| map.entrySet().stream().forEach((entry) -> {
String key = entry.getKey();
String value = entry.getValue();
})
|
parallelStream
1
2
3
4
| map.entrySet().parallelStream().forEach((entry) -> {
String key = entry.getKey();
String value = entry.getValue();
})
|
Interator
EntrySet
1
2
3
4
5
6
7
| Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while(iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
String key = entry.getKey();
String value = entry.getValue();
}
|
根据 Effective Java - 57,更推荐以下这种写法:
1
2
3
4
5
| for (Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry<String, String> entry = iterator.next();
String key = entry.getKey();
String value = entry.getValue();
}
|
KeySet
1
2
3
4
| for (Iteator<String> iterator = map.keySet().iterator(); iterator.hasNext(); ) {
String key = iterator.next();
String value = map.get(key);
}
|
🌟 一些操作
判空
1
2
3
4
5
| 🙋♂️
map.isEmpty();
🙅♂️
boolean b = map.size() == 0;
|
计数 / merge()
1
2
| public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
}
|
1
| map.merge(key, 1, Integer::sum);
|
removeIf()
🚧 注意:
Map
本身是没有 removeIf()
。
1
2
3
| map.entrySet().removeIf(entry -> {});
map.keySet().removeIf(key -> {});
map.values().removeIf(value -> {});
|
absent
1
| public V putIfAbsent(K key, V value);
|
1
2
3
4
5
6
7
| // 不存在 key 时,按 mappingFunction 添加 value
// 存在 key 不改变
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
}
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
}
|
default
1
| map.getOrDefault(key, 0);
|
🔗 参考