jdk接口-Map

Java Collections Framework - Map

public interface Map<K,V>

1 接口概括

  • key-value映射;不能包含重复key;一个key映射一个值
  • 取代 Dictionary
  • 提供三种访问map的方法: keySet()(),values(),entrySet()
  • 部分实现类有序,如TreeMap
  • 实现类应提供两种构造方法,Map()和Map(Map map)
  • 修改操作可能会抛出异常UnsupportedOperationException
  • 部分实现可能对key和value有限制
  • 内部使用equals方法判断相等
  • 执行递归遍历可能会失败
  • 属于Java Collections Framework 的一部分

2 主要方法

查询方法

  • 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)

批量操作

  • void putAll(Map<? extends K, ? extends V> m)
  • void clear()

视图

  • Set<K> keySet()
  • Collection<V> values()
  • Set<Map.Entry<K, V>> entrySet()

hash和equals

  • boolean equals(Object o)
  • int hashCode()

默认方法

  • default V getOrDefault(Object key, V defaultValue)
  • default void forEach(BiConsumer<? super K, ? super V> action)
  • default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)
  • default V putIfAbsent(K key, V value)
  • default boolean remove(Object key, Object value)
  • default boolean replace(K key, V oldValue, V newValue)
  • default V replace(K key, V value)
  • default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
  • default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)
  • default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)
  • default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)

3 内部接口

interface Entry<K,V>

3.1 方法

  • K getKey()
  • V getValue()
  • V setValue(V value)
  • boolean equals(Object o)
  • int hashCode()
  • public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey()
  • public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue()
  • public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp)
  • public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp)

4 抽象实现-AbstractMap

public abstract class AbstractMap<K,V> implements Map<K,V>

概述

  • 提供Map接口的骨架实现,以最大限度地减少实现此接口所需的工作量

唯一抽象方法

public abstract Set<Entry<K,V>> entrySet()

实现方法

此类实现map接口基本都是内部通过调用entrySet()这个抽象方法实现的

比如:
对size()方法的实现就是调用entrySet的size()

    public int size() {
        return entrySet().size();
    }

对containsValue()的实现同样如此

    public boolean containsValue(Object value) {
        Iterator<Entry<K,V>> i = entrySet().iterator();
        if (value==null) {
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (e.getValue()==null)
                    return true;
            }
        } else {
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (value.equals(e.getValue()))
                    return true;
            }
        }
        return false;
    }

成员变量(两个):
transient Set<K> keySet
transient Collection<V> values

Map接口中keySet()和values()实现就是返回的这2个成员变量
那么,这2个成员变量的初始化是在哪?
看代码其实是内部匿名实现AbstractSet类,也是调用entrySet()实现各个方法
values()方法实现类似(省略)

 public Set<K> keySet() {
        Set<K> ks = keySet;
        if (ks == null) {
            ks = new AbstractSet<K>() {
                public Iterator<K> iterator() {
                    return new Iterator<K>() {
                        private Iterator<Entry<K,V>> i = entrySet().iterator();

                        public boolean hasNext() {
                            return i.hasNext();
                        }

                        public K next() {
                            return i.next().getKey();
                        }

                        public void remove() {
                            i.remove();
                        }
                    };
                }

                public int size() {
                    return AbstractMap.this.size();
                }

                public boolean isEmpty() {
                    return AbstractMap.this.isEmpty();
                }

                public void clear() {
                    AbstractMap.this.clear();
                }

                public boolean contains(Object k) {
                    return AbstractMap.this.containsKey(k);
                }
            };
            keySet = ks;
        }
        return ks;
    }

equals实现

     public boolean equals(Object o) {
        if (o == this)
            return true;

        if (!(o instanceof Map))
            return false;
        Map<?,?> m = (Map<?,?>) o;
        if (m.size() != size())
            return false;

        try {
            Iterator<Entry<K,V>> i = entrySet().iterator();
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                K key = e.getKey();
                V value = e.getValue();
                if (value == null) {
                    if (!(m.get(key)==null && m.containsKey(key)))
                        return false;
                } else {
                    if (!value.equals(m.get(key)))
                        return false;
                }
            }
        } catch (ClassCastException unused) {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }

        return true;
    }

hashCode()实现

    public int hashCode() {
        int h = 0;
        Iterator<Entry<K,V>> i = entrySet().iterator();
        while (i.hasNext())
            h += i.next().hashCode();
        return h;
    }

5 Entry<K,V> 的实现

AbstractMap中提供了两种Entry的简单实现:  
一种是可变的Entry:SimpleEntry<K,V>
一种是不可变的Entry:SimpleImmutableEntry<K,V>  
两种实现的差异就只是在set方法上,前者正常修改,后者抛出 UnsupportedOperationException

6 JDK中对Map的实现

HashMap

源码阅读:https://www.cnblogs.com/carry1899/p/16933610.html

posted @   carry1899  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示