Java基础_集合_Map


博客原文: https://blog.csdn.net/zhoucheng05_13/article/details/79842142

一、Map的继承体系图

在这里插入图片描述

二、详解

第一层

包含AbstractMap抽象类和一个SortedMap接口。

AbstractMap

该类提供了一个Map接口的框架性实现,降低了实现Map接口的难度。该Map实现允许存入null值。它实现了Map接口的绝大多数方法。

SortedMap

  • 该接口继承了Map接口,它定义了key有序的Map。key如果实现Comparable接口,那么可以使用自然顺序进行排序。否则,在创建该map是提供外部comparator。对该map返回的视图(entrySet, keySet and values 方法)进行迭代遍历时就是根据key的顺序进行。该类还额外提供了几种方法来利用key有序这个特性。
  • 该接口要求所有的key都必须是可以进行比较的,要么通过k1.compareTo(k2),要么通过comparator.compare(k1, k2)进行比较。它同时还规定了所有通用的sorted map需要提供4个构造器,分别是:
    • 无参数构造器,给子类调用
    • 只含有一个Comparator的构造器
    • 只含有一个Map类型的参数,根据Map的key的自然顺序排序
    • 只含有一个SortedMap类型参数的构造器。
  • 接口提供了几个根据key的范围返回submaps的方法。这些范围都是半闭半开的。可以通过m.subMap(low, high+”\0”)来获得全闭范围。或者通过m.subMap(low+”\0”, high)来获得全开范围。该接口定义了几种利用key有序特性的方法:
    • subMap(K fromKey, K toKey):获取指定范围内的子Map视图。
    • headMap(K toKey)
    • tailMap(K fromKey)
    • firstKey():获取第一个key
    • lastKey():获取最后一个key

第二层

HashMap

HashMap是一个基于哈希表来存储键值对,以期获得O(1)的操作时间。它的底层实现时这样的:

  1. 定义了Node节点,该节点类似于链表节点。使用Node数组作为哈希表
  2. 在插入元素时,通过(n-1)&hash(hash为hashCode值>>>16)求得下标,并将其插入到该下标处。
  3. 如果下标处已经有元素了,那么就将元素插入到该哈希桶的链表头部。
  4. 执行删除时,同样通过(n-1)&hash求得下标,然后对该哈希桶的链表进行遍历,找到了就删除。

他有如下特点:

  1. 容量始终是2的整数次幂,默认容量是16.当用户通过构造函数指定初始容量时,该类会将其转化为大于它的最接近的2的幂。如用户输入30,那么初始容量会是32
  2. 默认的装填因子(load factor)是0.75.
  3. 它使用链地址法解决哈希冲突。
  4. 在哈希表大小大于68,且链的长度大于8时,HashMap会将链转化为红黑树结构,以提高查询效率。
  5. 在哈希表容量小于68,那么HashMap会对哈希表进行扩容,并重新哈希
  6. 在冲突链的长度大于8时,HashMap又会将红黑树转化为链表形式。
  7. 对HashMap进行遍历时,所花的时间与capacity而不是size成正比。因为它需要遍历Node数组的每一个位置。
  8. 当容量达到阈值(装载因子 * 容量)时,将Node数组增大2倍(因为容量室长要为2的幂)。

WeakHashMap & IdentityHashMap

  • WeakHashMap的key只保留对实际对象的弱引用,这意味着如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,WeakHashMap也可能自动删除这些key所对应的key-value对。
  • 在IdentityHashMap中,当且仅当两个key严格相等(key1==key2)时,IdentityHashMap才认为两个key相等;相对于普通HashMap而言,只要key1和key2通过equals()方法返回true,且它们的hashCode值相等即可。

HashTable

可以将HashTable理解为HashMap的线程安全版本,但是它们在哈希算法等方面还是存在一些不同。该类已经逐渐别废弃,在线程安全的场景下,JDK推荐使用HashMap代替Hashtable。如果需要一个线程安全的高并发实现,那么建议使用ComcurrentHashMap而不是该类。

  • HashTable具有如下特点:
  1. 通过在所有方法上添加Synchronized关键字进行同步锁定,因此线程安全,但效率很低
  2. 初始容量是11,如果用户指定了初始容量,那么HashTable不会做任何修改。
  3. load factor同样是0.75
  4. 使用Entry

TreeMap

TreeMap是一个基于NavigableMap的红黑树实现。该实现保证了containsKey、get、put、remove操作的log(n)时间界。
TreeMap最重要的特点是,使用了红黑树这种有序平衡二叉树来保持了key的顺序,同时又利用有序二叉树的常用操作的log(n)时间界。

注意,该方法不是同步的。如果要在多线程环境下使用,那么需要进行外部同步,通常是通过锁定一个外部对象,如果不存在这样的对象,那么应该使用Collections.synchronizedSortedMap进行包裹。

由该类集合视图方法返回的集合,它们的迭代器都是快速失败机制的。(快速失败机制有什么用?首先,快速失败是通过在每次进行操作前判断modCount是否等于expectedModCount,如果不等则说明集合在外部被修改了,那么抛出异常,终止遍历,将风险降到最小,而不是在未来的某一不确定的时间,冒任意不确定的风险。该机制并不可靠(为什么不可靠?存在不同步的并发修改时,不可能做出任何绝对的保证),不能依赖于该机制编程,官方文档中指明,该机制仅用于检测错误)

第三层

LinkedHashMap

LinkedHashMap是通过链表的方式使得插入变得有序的Map接口实现。这个实现是为了解决HashMap和HashTable无序问题,而又不增加像TreeMap那样的成本。它基于HashMap,并在HashMap的基础上为每个节点增加了一个双向链,形成了一个双向链表,以此来保证了元素的有序。

重点: LinkedHashMap的一个特殊的构造器LinkedHashMap(int,float,boolean)被用来创建一个从最近最少到最近被访问的访问顺序排序的LinkedHashMap。这样的map非常适合用于实现LRU缓存。关于LinkedHashMap与LRU的关系。
这里请参考:https://blog.csdn.net/zhoucheng05_13/article/details/79832885

  • LinkedHashMap与HashMap的不同点有:

    1. LinkedHashMap在视图上的迭代器需要与size成比例的时间,与容量无关。而HashMap的迭代器依赖于哈希桶的容量,这将花费比LinkedHashMap更多的时间。
    2. LinkedHashMap的initial capacity和load facotry参数的定义与HashMap中一样。不过,需要注意的是,初始容量过高给LinkedHashMap带来的影响比HashMap要小得多。因为LinkedHashMap的遍历是通过链表完成(HashMap是通过遍历所有哈希桶,时间与容量成正比)。由于添加了链表,因此LinkedHashMap的性能会略低于HashMap。
    3. LinkedHashMap可以通过accessOrder参数来选择两种不同的排序方式:accessOrder为true时,以元素的访问顺序排序。为false时(默认情况),以元素的插入顺序排序。

properties

key和value都只能是String类型的,可使用成员方法load将.properties文件中的键值对加载进来,也可以从xml文件中加载属性列表(键值对)。

  • 使用load方法从读取属性列
    1. load(InputStream inStream) 从输入流中读取属性列表(键和元素对)。
    2. load(Reader reader) 按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
    3. loadFromXML(InputStream in) 将指定输入流中由 XML 文档所表示的所有属性加载到此属性表中。
  • 使用store方法
    1. store(OutputStream out, String comments) 将此 Properties 表中的属性列表(键和元素对)写入输出流。
    2. store(Writer writer, String comments) 将此 Properties 表中的属性列表(键和元素对)写入输出字符。
    3. storeToXML(OutputStream os, String comment) 发出一个表示此表中包含的所有属性的 XML 文档。
    4. storeToXML(OutputStream os, String comment, String encoding) 使用指定的编码发出一个表示此表中包含的所有属性的 XML 文档。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值