java集合系列12 Map

来源:互联网 发布:directx 9.0修复软件 编辑:程序博客网 时间:2024/05/16 15:36

前言

前面的一系列文章,我们依次介绍了Collection AbstractCollection List AbstractList ArrayList LinkedList,那我们最终的目的是研究我们经常使用的ArrayList, LinkedList。
那在List接口下还有好多实现类比如Vector, Stack。我觉得可以先略过。

另外Set的实现类都是基于Map来实现的(如,HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的),所以接下来我会研究Map下的重要类

这里写图片描述

如上图:

  • Map是映射接口,Map中存储的内容是键值对(key-value)
  • AbstractMap,是继承于Map的抽象类,它实现了Map中的大部分API。其它Map的实现类可以通过继承AbstractMap来减少重复编码
  • SortedMap是继承于Map接口的。SortedMap中的内容是排序的键值对,排序的方法是通过比较器(Comparator)
  • NavigableMap是继承于SortedMap接口。相比于SortedMap,NavigableMap有一系列的导航方法:如”获取大于/等于某对象的键值对“、”获取小于/等于某对象的键值对“等等
  • TreeMap继承于AbstractMap,且实现了NavigableMap接口;因此,TreeMap中的内容是”有序的键值对“
  • HashMap继承于AbstractMap,但没实现NavigableMap接口;因此,HashMap的内容是”键值对,但不保证次序“
  • Hashtable虽然不是继承于AbstractMap,但它继承于Dictionary(Dictionary也是键值对的接口),而且也实现Map接口;因此,Hashtable的内容也是”键值对,也不保证次序“。但和HashMap相比,Hashtable是线程安全的
  • WeakHashMap 继承于AbstractMap。它和HashMap的键类型不同,WeakHashMap的键是“弱键”。

上文转自 Java 集合系列09之 Map架构

Map接口文档

一个映射键值对的对象。一个映射不能包含重复的键,每个键至多只能映射一个值

此接口取代Dictionary类,Dictionary类是一个抽象类而不是一个接口

Map接口提供三种集合视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。一个被定义的Map的顺序取决于此Map集合视图迭代器返回元素的顺序。一些Map实现如TreeMap类,明确保证其顺序;其他的实现则不保证顺序,如HashMap

注意:将可变对象用作映射的键时要额外小心。映射的行为是不确定的如果作为键的对象改变其值并且影响了equals的比较。一个额外的禁止是映射不允许将此映射自身作为值,特别的警告建议:这样映射下的hashCode和equals方法不在是良好的定义

所有通用的映射实现类应该提供两个标准的构造器:一个创建空映射的无参构造器,一个创建具有相同键值对映射的只有唯一Map类型参数的有参构造器。在事实上,后一个构造器方法允许用户复制任何映射,产生一个与指定参数等价的并拥有渴望类型的映射。尽管没有方法强制遵守此建议(因为接口不能包含构造器)但JDK中所有通用的映射实现都遵从它。

此接口包含具有破坏性的方法可修改其操作的映射,如果此映射不支持此操作可以抛出UnsupportedOperationException。如果是这样,那么在调用对映射无效时,这些方法可以(但不要求)抛出UnsupportedOperationException。例如,在一个不可变的映射上调用putAll(Map)方法,但不是必须的,抛出异常,如果此map与给定的参数重叠部分是空

一些映射实现对其所能包含的键和值有限制。例如,一些实现不允许null键和值,一些实现对其所包含的键的类型有限制。尝试插入一个不合适的键或值会抛出一个未检查异常,通常是NullPointerExcception或ClassCastExcetpion。尝试查询是否存在一个不合适的值或键可能抛出一个异常,或仅仅返回false;一些实现显示出前者的行为,一些会展现出后者的行为。一般来说,试图对不合格的键或值执行操作且该操作的完成不会导致不合格的元素被插入映射中时,将可能抛出一个异常,也可能操作成功,这取决于实现本身。这样的异常在此接吕的堆满中标记为”可选“

集合中的许多方法是根据Object.equals方法定义的。例如,containsKey(Object)的说明 containsKey(Object)的方法说明:”当且仅当此映射包含一个映射关满足(key == null ? k == null : key.equals(k)时返回true“。不应将此规范解释为:调用具有非空参数key的Map.containsKey将导致对任意的键k调用key.equals(k)。实现可随意进行优化,以避免调用equals,例如,可首先比较两个键的哈希码(Object.hashCode() 规范保证哈希码不相等的两个对象不会相等)。一般来说,只要实现者认为合适,各种 Collections Framework 接口的实现可随意利用底层 Object 方法的指定行为。

源码

public interface Map<K, V> {    //查询方法    //返回此映射包含映射关系的数量。    // 如果数量大于Integer.MAX_VALUE, 返回Integer.MAX_VALUE    int size();    //是否为空    boolean isEmpty();    //如果此映射的一个映射关系包含指定的key返回true    //通常来讲 此映射的一个映射关系k 其键为 key    //当且仅当 key == null ? k == null : key.equals(k)为true时返回true    boolean containsKey(Object key);    //返回true 如果此映射映射到至少包含此value值的映射关系    boolean containsValue(Object value);    //返回指定key映射到的value    //或者如果此映射没有包含此key的映射关系返回null    //如果此映射允许null值,返回的null值并不一定代表此映射不包含含有此key的映射关系    //也有可能代表此映射的某个映射关系包含的key就为null    //containsKey操作可以用来区别这两种情况    V get(Object key);    //改变操作    //在此映射中,用指定的值与指定的键关联(可选的)    //如果此映射已经包含了具有此key的映射关系,旧值会被指定值替换    //返回被替换的旧值,如果不存在返回null    V put(K key, V value);    //删除具有指定key的映射关系,返回此映射关系的value    //如果没有返回null    V remove(Object key);    //大数量的操作    //从指定映射中复制所有的映射关系到此映射(可选的操作)    //当操作进行时,指定映射被改变了 的行为不确定    void putAll(Map<? extends K, ? extends V> m);    //从此映射中移除所有的映射关系(可选的操作)    void clear();    //视图    //返回此映射中包含的键的Set视图。此Set受映射支持,所以对映射的更改    //会影响到此Set,反之亦然。如果在迭代此Set时,映射被更改(除了迭代器自身的remover操作)    //迭代的结果是不确定的    //此Set支持删除元素(从此映射中删除相关系的映射关系),通过Iterator.remove,Set.remove, removeAll,    //retainAll 和clear操作。不支持add或addAll操作    Set<K> keySet();    //方法说明同上    Collection<?> values();    //方法说明同上    Set<Map.Entry<K, V>> entrySet();    //映射项(键值对)。Map.entrySet方法返回此映射的集合视图,该集合的元素就是此类。    //获得映射项引用的唯一 方法是通过此 collection 视图的迭代器来实现。    //这些 Map.Entry 对象仅 在迭代期间有效;    //更确切地讲,如果在迭代器返回项之后修改了底层映射,则某些映射项的行为是不确定的,除了通过 setValue 在映射项上执行操作之外。    interface Entry<K, V>{        //返回与此项对应的键        K getKey();        //返回与此项对应的值        V getValue();        //用指定的值替换与此项对应的值(可选操作)        V setValue(V value);        //比较指定对象与此项的相等性        boolean equals(Object o);        //返回此映射项的哈希码值        int hashCode();    }    //比较和哈希    boolean equals(Object o);    int hashCode();}

参考

  • Java 集合系列09之 Map架构
  • JDK1.8源码
0 0
原创粉丝点击