前言

Java的Map接口是非常常用的接口,HashMap就主要继承它,这里罗列些基本的常用接口。源码按照分类来处理。

Query操作

包含基本的map常识操作接口,这些接口完成了基本的map。

  1. int size();
  2. boolean isEmpty();
  3. boolean containsKey(Object key);
  4. boolean containsValue(Object value);
  5. V get(Object key);
  6. V put(K key, V value);
  7. V remove(Object key);

Bulk操作

一些批量操作方法。

  1. void putAll(Map<? extends K, ? extends V> m);
  2. void clear();

Views

最常用的一些view方法,用于迭代等操作。

  1. Set<K> keySet();
  2. Collection<V> values();
  3. Set<Map.Entry<K, V>> entrySet();

这里用到了Map.Entry接口,这是个类的内部接口。源码中核心的代码如下:

  1. interface Entry<K,V> {
  2. K getKey();
  3. V getValue();
  4. V setValue(V value);
  5. ...
  6. }

默认方法(1.8之后)

在java 1.8之后,接口可以添加默认方法,这时候Map有了很多使用的默认方法。

getOrDefault

当key存在映射时,进行返回。否则返回默认值。

  1. default V getOrDefault(Object key, V defaultValue) {
  2. V v;
  3. return (((v = get(key)) != null) || containsKey(key))
  4. ? v
  5. : defaultValue;
  6. }

forEarch

对map进行方便的循环操作。

  1. default void forEach(BiConsumer<? super K, ? super V> action) {
  2. Objects.requireNonNull(action);
  3. for (Map.Entry<K, V> entry : entrySet()) {
  4. K k;
  5. V v;
  6. try {
  7. k = entry.getKey();
  8. v = entry.getValue();
  9. } catch(IllegalStateException ise) {
  10. // this usually means the entry is no longer in the map.
  11. throw new ConcurrentModificationException(ise);
  12. }
  13. action.accept(k, v);
  14. }
  15. }

replaceAll

对map的每一个key,value使用给定的function进行替换操作。

  1. default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
  2. Objects.requireNonNull(function);
  3. for (Map.Entry<K, V> entry : entrySet()) {
  4. K k;
  5. V v;
  6. try {
  7. k = entry.getKey();
  8. v = entry.getValue();
  9. } catch(IllegalStateException ise) {
  10. // this usually means the entry is no longer in the map.
  11. throw new ConcurrentModificationException(ise);
  12. }
  13. // ise thrown from function is not a cme.
  14. v = function.apply(k, v);
  15. try {
  16. entry.setValue(v);
  17. } catch(IllegalStateException ise) {
  18. // this usually means the entry is no longer in the map.
  19. throw new ConcurrentModificationException(ise);
  20. }
  21. }
  22. }

putIfAbsent

put对应的entry。当key对应的value缺席不存在时,进行设置操作。

  1. default V putIfAbsent(K key, V value) {
  2. V v = get(key);
  3. if (v == null) {
  4. v = put(key, value);
  5. }
  6. return v;
  7. }

remove

移除指定key,key对应的value必须与参数一致。

  1. default boolean remove(Object key, Object value) {
  2. Object curValue = get(key);
  3. if (!Objects.equals(curValue, value) ||
  4. (curValue == null && !containsKey(key))) {
  5. return false;
  6. }
  7. remove(key);
  8. return true;
  9. }

replace

替换这个entry,当且仅当key,value均一致时,和remove方法类似。

  1. default boolean replace(K key, V oldValue, V newValue) {
  2. Object curValue = get(key);
  3. if (!Objects.equals(curValue, oldValue) ||
  4. (curValue == null && !containsKey(key))) {
  5. return false;
  6. }
  7. put(key, newValue);
  8. return true;
  9. }

类似的下面方法也是replace,当key存在时才会替换。

  1. default V replace(K key, V value) {
  2. V curValue;
  3. if (((curValue = get(key)) != null) || containsKey(key)) {
  4. curValue = put(key, value);
  5. }
  6. return curValue;
  7. }

computeIfAbsent

当key不存在时,使用function计算获取新的value,当value不为null时,进行put。

  1. default V computeIfAbsent(K key,
  2. Function<? super K, ? extends V> mappingFunction) {
  3. Objects.requireNonNull(mappingFunction);
  4. V v;
  5. if ((v = get(key)) == null) {
  6. V newValue;
  7. if ((newValue = mappingFunction.apply(key)) != null) {
  8. put(key, newValue);
  9. return newValue;
  10. }
  11. }
  12. return v;
  13. }

computeIfPresent

当key存在时,使用function计算新value,value存在时,进行替换,为null时,进行删除。

  1. default V computeIfPresent(K key,
  2. BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
  3. Objects.requireNonNull(remappingFunction);
  4. V oldValue;
  5. if ((oldValue = get(key)) != null) {
  6. V newValue = remappingFunction.apply(key, oldValue);
  7. if (newValue != null) {
  8. put(key, newValue);
  9. return newValue;
  10. } else {
  11. remove(key);
  12. return null;
  13. }
  14. } else {
  15. return null;
  16. }
  17. }

compute

针对key,直接进行计算操作。返回的新value,为null的话,直接移除,不为null进行替换。是上面2个方法的宽泛实现。

  1. default V compute(K key,
  2. BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
  3. Objects.requireNonNull(remappingFunction);
  4. V oldValue = get(key);
  5. V newValue = remappingFunction.apply(key, oldValue);
  6. if (newValue == null) {
  7. // delete mapping
  8. if (oldValue != null || containsKey(key)) {
  9. // something to remove
  10. remove(key);
  11. return null;
  12. } else {
  13. // nothing to do. Leave things as they were.
  14. return null;
  15. }
  16. } else {
  17. // add or replace old mapping
  18. put(key, newValue);
  19. return newValue;
  20. }
  21. }

merge

针对key,设置新的value。value不为null时,进行function的操作,否则就是value。之后判断新的value是否为null,决定remove还是put操作。

  1. default V merge(K key, V value,
  2. BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
  3. Objects.requireNonNull(remappingFunction);
  4. Objects.requireNonNull(value);
  5. V oldValue = get(key);
  6. V newValue = (oldValue == null) ? value :
  7. remappingFunction.apply(oldValue, value);
  8. if(newValue == null) {
  9. remove(key);
  10. } else {
  11. put(key, newValue);
  12. }
  13. return newValue;
  14. }