码迷,mamicode.com
首页 > 其他好文 > 详细

Map、AbstractMap、SortedMap、NavigableMap介绍(JDK1.8)

时间:2020-06-29 11:51:06      阅读:49      评论:0      收藏:0      [点我收藏+]

标签:uid   简介   eal   技术   sub   有一个   未定义   res   app   

简介

Map接口与常见实现类的UML图:

技术图片

  • Map实现的类存储对象是键值对

  • AbstractMap抽象类实现了Map接口部分方法,那么其他Map实现类可以通过继承AbstractMap来减少代码编写。

  • 实现了SortedMap接口的Map实现类具有排序键值对的功能。

  • NavigableMap接口继承自SortedMap接口,其具有获取大于|等于某对象的键值对、小于|等于某对象的键值对。

  • Dictionary抽象类存储键值对,与Map类似,但现在该类已过时。

  • HashMap继承AbstractMap类,能存储键值对,但不能保证插入次序。

  • HashTable实现Map、继承Dictionary,即也能存储键值对,但不保证次序。它是一个线程安全的类。

  • LinkedHashMap实现Map接口,继承HashMap,能存储键值对,也保证次序。

  • TreeMap继承AbstractMap类,也实现了NavigableMap接口,即内部是是有序的键值对。


Map

  • Map是一个操作键值对映射的接口,一个键只能有一个,一个键对应一个值。

  • Map接口提供三种视图,分别是:键集、值集、键值集。

  • Map有些实现类能保证取出键值对与插入键值对次序一致,如LinkedHashMap;有些实现类能通过排序键值对, 如TreeMap。

常用API
Modifier and Type Method
void clear()
default V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)
default V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)
default V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)
boolean containsKey(Object key)
boolean containsValue(Object value)
Set<Map.Entry<K,V>> entrySet()
boolean equals(Object o)
default void forEach(BiConsumer<? super K,? super V> action)
V get(Object key)
default V getOrDefault(Object key, V defaultValue)
int hashCode()
boolean isEmpty()
Set<K> keySet()
default V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)
V put(K key, V value)
void putAll(Map<? extends K,? extends V> m)
default V putIfAbsent(K key, V value)
V remove(Object key)
default boolean remove(Object key, Object value)
default V replace(K key, V value)
default boolean replace(K key, V oldValue, V newValue)
default void replaceAll(BiFunction<? super K,? super V,? extends V> function)
int size()
Collection<V> values()

keySet()返回键集,values()返回值集,entrySet()返回键值集


Map.Entry

Entry是Map内部接口,其功能是对键值对进行操作。

API

Modifier and Type Method and Description
static <K extends Comparable<? super K>,V>Comparator<Map.Entry<K,V>> comparingByKey()返回一个比较 ,按键自然顺序比较Map.Entry
static <K,V> Comparator<Map.Entry<K,V>> comparingByKey(Comparator<? super K> cmp)返回一个比较器,比较Map.Entry按键使用给定的Comparator
static <K,V extends Comparable<? super V>>Comparator<Map.Entry<K,V>> comparingByValue()返回一个比较器,比较Map.Entry的自然顺序值。
static <K,V> Comparator<Map.Entry<K,V>> comparingByValue(Comparator<? super V> cmp)返回一个比较 ,使用给定的Comparator比较Map.Entry的值。
boolean equals(Object o)将指定的对象与此条目进行比较以获得相等性。
K getKey()返回与此条目相对应的键。
V getValue()返回与此条目相对应的值。
int hashCode()返回此映射条目的哈希码值。
V setValue(V value)用指定的值替换与该条目相对应的值(可选操作)。

AbstractMap

属性
    transient Set<K>        keySet;键集视图
    transient Collection<V> values;值集视图
源码分析
		//唯一一个构造方法
		protected AbstractMap() {}
	
		//返回键值集元素个数
    public int size() {
        return entrySet().size();
    }
		
		//判断该容器是否为空
    public boolean isEmpty() {
        return size() == 0;
    }

		//查询该容器是否存在值为value
    public boolean containsValue(Object value) {
      //获取键值集的迭代器
        Iterator<Entry<K,V>> i = entrySet().iterator();
      //指定值为null的情况
        if (value==null) {
          	//通过迭代器遍历该容器
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (e.getValue()==null)
                    return true;
            }
        } else {//指定值不为null情况
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (value.equals(e.getValue()))
                    return true;
            }
        }
        return false;
    }
		
		//查询该容器是否存在键为key
    public boolean containsKey(Object key) {
      	//获取键集视图的迭代器
        Iterator<Map.Entry<K,V>> i = entrySet().iterator();
      	//指定值为null的情况
        if (key==null) {
          //通过迭代器遍历该容器
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (e.getKey()==null)
                    return true;
            }
        } else {
          //指定值不为null的情况
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (key.equals(e.getKey()))
                    return true;
            }
        }
        return false;
    }

		//通过键获取值,若查找不到返回null。
    public V get(Object key) {
      	//获取键值集的迭代器
        Iterator<Entry<K,V>> i = entrySet().iterator();
        if (key==null) {
          //通过迭代器遍历该容器
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
              //比较键值
                if (e.getKey()==null)
                    return e.getValue();
            }
        } else {
            while (i.hasNext()) {
              //通过迭代器遍历该容器
                Entry<K,V> e = i.next();
              //比较键值
                if (key.equals(e.getKey()))
                    return e.getValue();
            }
        }
        return null;
    }
		
		//通过键移除指定的键值对
    public V remove(Object key) {
      //获取键值集的迭代器
        Iterator<Entry<K,V>> i = entrySet().iterator();
        Entry<K,V> correctEntry = null;
        if (key==null) {
          //通过迭代器遍历该容器
            while (correctEntry==null && i.hasNext()) {
                Entry<K,V> e = i.next();
                if (e.getKey()==null)
                    correctEntry = e;
            }
        } else {
          //通过迭代器遍历该容器
            while (correctEntry==null && i.hasNext()) {
                Entry<K,V> e = i.next();
                if (key.equals(e.getKey()))
                    correctEntry = e;
            }
        }

      	//oldValue为旧值
        V oldValue = null;
        if (correctEntry !=null) {
            oldValue = correctEntry.getValue();
          	//调用迭代器移除方法
            i.remove();
        }
        return oldValue;
    }

		//添加其他容器数据
    public void putAll(Map<? extends K, ? extends V> m) {
      	//遍历容器内数据并一一添加
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
            put(e.getKey(), e.getValue());
    }

		//对容器内所有映射
    public void clear() {
      	//先获取键值集再调用删除方法。
        entrySet().clear();
    }
		
		//获取键集视图
    public Set<K> keySet() {
        Set<K> ks = keySet;
        if (ks == null) {
          //如果成员变量 keySet 为 null,创建个空的 AbstractSet,并完成Iterator<K>()、size()、isEmpty()、clear()、contains(Object k)方法。
            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;
    }

		//获取值集视图
    public Collection<V> values() {
        Collection<V> vals = values;
      //如果成员变量 vals 为 null,创建个空的 AbstractSet,并完成Iterator<K>()、size()、isEmpty()、clear()、contains(Object k)方法。
        if (vals == null) {
            vals = new AbstractCollection<V>() {
                public Iterator<V> iterator() {
                    return new Iterator<V>() {
                        private Iterator<Entry<K,V>> i = entrySet().iterator();

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

                        public V next() {
                          //获取值
                            return i.next().getValue();
                        }

                        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 v) {
                    return AbstractMap.this.containsValue(v);
                }
            };
            values = vals;
        }
        return vals;
    }

		//获取键值集方法未定义
    public abstract Set<Entry<K,V>> entrySet();

		//判断对象o是否等于当前容器
    public boolean equals(Object o) {
      	//判断地址相等
        if (o == this)
            return true;
				//判断是否为同一类型
        if (!(o instanceof Map))
            return false;
      	//强转为 Map
        Map<?,?> m = (Map<?,?>) o;
      	//判断大小是否相等
        if (m.size() != size())
            return false;
			
        try {
          //下面就是使用容器的迭代器遍历元素,在判断对象o的map 是否包含指定键值对
            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;
    }
		
		
//整个 map 的 hashCode()
    public int hashCode() {
        int h = 0;
        Iterator<Entry<K,V>> i = entrySet().iterator();
        while (i.hasNext())
          	//是所有 Entry 哈希值的和
            h += i.next().hashCode();
        return h;
    }

   	//返回此 AbstractMap实例的浅拷贝:键和值本身不被克隆。
    protected Object clone() throws CloneNotSupportedException {
        AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone();
        result.keySet = null;
        result.values = null;
        return result;
    }

		//判读o1,02是否相等
    private static boolean eq(Object o1, Object o2) {
        return o1 == null ? o2 == null : o1.equals(o2);
    }
		
AbstractMap.SimpleEntry类:

表示可变的键值对

 public static class SimpleEntry<K,V>
        implements Entry<K,V>, java.io.Serializable
    {
        private static final long serialVersionUID = -8499721149061103585L;

        private final K key;
        private V value;

        public SimpleEntry(K key, V value) {
            this.key   = key;
            this.value = value;
        }

        public SimpleEntry(Entry<? extends K, ? extends V> entry) {
            this.key   = entry.getKey();
            this.value = entry.getValue();
        }

        public K getKey() {
            return key;
        }

        public V getValue() {
            return value;
        }
				//可以替换键值中的旧值
        public V setValue(V value) {
            V oldValue = this.value;
            this.value = value;
            return oldValue;
        }

        public int hashCode() {
            return (key   == null ? 0 :   key.hashCode()) ^
                   (value == null ? 0 : value.hashCode());
        }

        public String toString() {
            return key + "=" + value;
        }

    }
AbstractMap.SimpleImmutableEntry类:

表示一个不可变的键值对

public static class SimpleImmutableEntry<K,V>
        implements Entry<K,V>, java.io.Serializable
    {
        private static final long serialVersionUID = 7138329143949025153L;

        private final K key;
        private final V value;

        public SimpleImmutableEntry(K key, V value) {
            this.key   = key;
            this.value = value;
        }

        public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) {
            this.key   = entry.getKey();
            this.value = entry.getValue();
        }

        public K getKey() {
            return key;
        }

        public V getValue() {
            return value;
        }
				//修改键值则抛出异常
        public V setValue(V value) {
            throw new UnsupportedOperationException();
        }
				//判断与另外一个键值对是否相等
        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
            return eq(key, e.getKey()) && eq(value, e.getValue());
        }

        public int hashCode() {
            return (key   == null ? 0 :   key.hashCode()) ^
                   (value == null ? 0 : value.hashCode());
        }

        public String toString() {
            return key + "=" + value;
        }
    }

SortedMap接口

API

Modifier and Type Method and Description
Comparator<? super K> comparator()
Set<Map.Entry<K,V>> entrySet()
K firstKey()
SortedMap<K,V> headMap(K toKey)
Set<K> keySet()
K lastKey()
SortedMap<K,V> subMap(K fromKey, K toKey)
SortedMap<K,V> tailMap(K fromKey)
Collection<V> values()
源码
public interface SortedMap<K,V> extends Map<K,V> {
    //返回与此有序映射关联的比较器,如果使用键的自然顺序,则返回 null
    Comparator<? super K> comparator();

  	//返回此有序映射的部分视图,其键值从 fromKey(包括)到 toKey(不包括)。
    SortedMap<K,V> subMap(K fromKey, K toKey);

  	//返回此有序映射的部分元素,其元素的键值应该小于 toKey。
    SortedMap<K,V> headMap(K toKey);

  	//返回有序映射的部分视图,其键大于或等于 fromKey。
    SortedMap<K,V> tailMap(K fromKey);
  
		//返回有序映射中当前第一个(最小的)键。
    K firstKey();

  	//返回有序映射中当前最后一个(最大的)键。
    K lastKey();

  	//键集视图
    Set<K> keySet();

  	//值集视图
    Collection<V> values();

  	//键值集视图
    Set<Map.Entry<K, V>> entrySet();
}


简介

NavigableMap是SortedMap的子接口,具有SortedMap更多功能。

? 方法 lowerEntry、floorEntry、ceilingEntry 和 higherEntry 分别返回与小于、小于等于、大于等于、大于给定键的键关联的 Map.Entry 对象,如果不存在这样的键,则返回 null。

? 类似地,方法 lowerKey、floorKey、ceilingKey 和 higherKey 只返回关联的键。

? firstEntry、pollFirstEntry、lastEntry 和 pollLastEntry 方法,它们返回和/或移除最小和最大的映射关系(如果存在),否则返回 null。所有这些方法是为查找条目而不是遍历条目而设计的。

API
Modifier and Type Method
Map.Entry<K,V> ceilingEntry(K key)
K ceilingKey(K key)
NavigableSet<K> descendingKeySet()
NavigableMap<K,V> descendingMap()
Map.Entry<K,V> firstEntry()
Map.Entry<K,V> floorEntry(K key)
K floorKey(K key)
SortedMap<K,V> headMap(K toKey)
NavigableMap<K,V> headMap(K toKey, boolean inclusive)
Map.Entry<K,V> higherEntry(K key)
K higherKey(K key)
Map.Entry<K,V> lastEntry()
Map.Entry<K,V> lowerEntry(K key)
K lowerKey(K key)
NavigableSet<K> navigableKeySet()
Map.Entry<K,V> pollFirstEntry()
Map.Entry<K,V> pollLastEntry()
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
SortedMap<K,V> subMap(K fromKey, K toKey)
SortedMap<K,V> tailMap(K fromKey)
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive)

Map、AbstractMap、SortedMap、NavigableMap介绍(JDK1.8)

标签:uid   简介   eal   技术   sub   有一个   未定义   res   app   

原文地址:https://www.cnblogs.com/zitai/p/13206765.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!