前言
Java的Map接口是非常常用的接口,HashMap就主要继承它,这里罗列些基本的常用接口。源码按照分类来处理。
Query操作
包含基本的map常识操作接口,这些接口完成了基本的map。
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
V put(K key, V value);
V remove(Object key);
Bulk操作
一些批量操作方法。
void putAll(Map<? extends K, ? extends V> m);
void clear();
Views
最常用的一些view方法,用于迭代等操作。
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
这里用到了Map.Entry接口,这是个类的内部接口。源码中核心的代码如下:
interface Entry<K,V> {
K getKey();
V getValue();
V setValue(V value);
...
}
默认方法(1.8之后)
在java 1.8之后,接口可以添加默认方法,这时候Map有了很多使用的默认方法。
getOrDefault
当key存在映射时,进行返回。否则返回默认值。
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
forEarch
对map进行方便的循环操作。
default void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}
replaceAll
对map的每一个key,value使用给定的function进行替换操作。
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Objects.requireNonNull(function);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
// ise thrown from function is not a cme.
v = function.apply(k, v);
try {
entry.setValue(v);
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
}
}
putIfAbsent
put对应的entry。当key对应的value缺席不存在时,进行设置操作。
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
v = put(key, value);
}
return v;
}
remove
移除指定key,key对应的value必须与参数一致。
default boolean remove(Object key, Object value) {
Object curValue = get(key);
if (!Objects.equals(curValue, value) ||
(curValue == null && !containsKey(key))) {
return false;
}
remove(key);
return true;
}
replace
替换这个entry,当且仅当key,value均一致时,和remove方法类似。
default boolean replace(K key, V oldValue, V newValue) {
Object curValue = get(key);
if (!Objects.equals(curValue, oldValue) ||
(curValue == null && !containsKey(key))) {
return false;
}
put(key, newValue);
return true;
}
类似的下面方法也是replace,当key存在时才会替换。
default V replace(K key, V value) {
V curValue;
if (((curValue = get(key)) != null) || containsKey(key)) {
curValue = put(key, value);
}
return curValue;
}
computeIfAbsent
当key不存在时,使用function计算获取新的value,当value不为null时,进行put。
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v;
if ((v = get(key)) == null) {
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
put(key, newValue);
return newValue;
}
}
return v;
}
computeIfPresent
当key存在时,使用function计算新value,value存在时,进行替换,为null时,进行删除。
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue;
if ((oldValue = get(key)) != null) {
V newValue = remappingFunction.apply(key, oldValue);
if (newValue != null) {
put(key, newValue);
return newValue;
} else {
remove(key);
return null;
}
} else {
return null;
}
}
compute
针对key,直接进行计算操作。返回的新value,为null的话,直接移除,不为null进行替换。是上面2个方法的宽泛实现。
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue = get(key);
V newValue = remappingFunction.apply(key, oldValue);
if (newValue == null) {
// delete mapping
if (oldValue != null || containsKey(key)) {
// something to remove
remove(key);
return null;
} else {
// nothing to do. Leave things as they were.
return null;
}
} else {
// add or replace old mapping
put(key, newValue);
return newValue;
}
}
merge
针对key,设置新的value。value不为null时,进行function的操作,否则就是value。之后判断新的value是否为null,决定remove还是put操作。
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
V oldValue = get(key);
V newValue = (oldValue == null) ? value :
remappingFunction.apply(oldValue, value);
if(newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}