Java集合Map随笔

Map:双列数据,存储键值对的数据(实体)

1.HashMap:作为Map的主要实现类;线程不安全、效率高;可存储null的key和value。底层在jdk7及以前是数组加链表;jdk8及以后是数组加链表加红黑树。

2.LinkedHashMap:HashMap的子类;保证遍历map元素时,可以按照添加顺序遍历。因为在原有HashMap底层结构基础上,添加了一对指针,指向前一个数据和后一个数据。适用于频繁的遍历操作。

3.TreeMap:保证按照添加的键值对进行排序,实现排序遍历。排序原则:对键进行自然排序或定制排序。底层使用红黑树。

4.HashTable:作为古老的实现类;线程安全、效率低;不能存储null的key和value。

5.Properties:HashTable的子类;常用来处理配置文件。键和值都是String类型的。

6.HashMap底层实现原理:以jdk7为例说明:调用空参构造器时创建默认长度为16的Entry类型数组。添加键值对key1-value1时:调用key1所在类的hashcode方法求出key1的哈希值,根据此哈希值通过某种算法计算出该键值对在数组中的索引位置。若此位置无数据添加成功。若此位置存在一个数据或以链表形式存在多个数据,则比较key1和已存在的一个或多个数据的哈希值,若都不相同则添加成功。若key1和已存在的某个数据如key2-value2的哈希值相同,则调用key1所在类的equals(key2)方法。若返回值为false则添加成功。若返回值为true则修改相同键的值为最新要添加的值(使用value1替换原有值value2)。在不断的添加过程中,会涉及到扩容问题,当哈希表长度大于扩容临界值且要插入的索引位置为非空时(哈希碰撞),默认的扩容方式为:将数组容量扩大为原来的2倍,并将原有的数据复制过来,复制过程中会重新计算每个数据在数组中的索引位置。

7.为什么扩容条件为大于临界值而不是存满?
因为HashMap的数据结构有可能不会存满,而是不断的加长链表。为了尽可能的减小链表的长度,把扩容条件设为大于临界值而不是存满。

8.源码中的知识点:DEFAULT_INITIAL_CAPACITY:默认数组容量为16;当调用带参构造器创建HashMap对象时,若指定的容量不是2的整数次幂,创建的数组容量为大于该参数的最小2的整数次幂;DEFAULT_LOAD_FACTOR:HashMap的默认加载因子为0.75;threshold:扩容的临界值为数组当前容量乘加载因子;TREEIFY_THRESHOLD:Bucket(数组某一索引位置上)中的链表长度大于该默认值8,且哈希表长度大于64时,转化为红黑树;MIN_TREEIFY_CAPACITY:桶(Bucket)中的Node被树化时最小的Hash表容量,默认为64,若桶中链表长度大于TREEIFY_THRESHOLD但哈希表长度不大于MIN_TREEIFY_CAPACITY则执行resize()进行扩容。

9.Collection与Collections的区别:Collection是存储单列数据的集合的接口,子接口有List和Set。Collections是操作Collection的工具类,所有方法均为静态方法。

jdk8相较于jdk7在底层实现的不同:

1.调用空参构造器时底层没有创建长度为16的数组。

2.jdk8底层数组为Node[]而非Entry[],仅仅类型名称改变其结构没变。

3.首次调用put()方法时,底层创建长度为16的数组。

4.jdk7底层数据结构为:数组+链表。jdk8底层数据结构为:数组+链表+红黑树。当数组的某一个索引位置上的元素以链表的形式存在的数据个数>8且当前数组的长度>64时,此时此索引位置上的所有数据改为使用红黑树存储。因为当数组某一索引位置上的数据过多时,在链表中查找指定数据需要逐个遍历,效率低。改用红黑树存储,每次查找都是二分查找,效率高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值