java集合框架Map

Map
  Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够根据key查找value,key和value可以是任意类型的对象
  key和value属于Entry类的对象实例
  key值不能重复
  一个value可以对应多个key,一个key只能对应一个value
  Map的泛型:Map<K, V>   //K为key值的类型,V为value值的类型
HashMap
  HashMap中的Entry对象是无序排列的
  key值和value值可以为null,但是只能有一个key为null,因为key不可重复
  实现原理:
  底层是使用数组加链表的方式进行实现的,当添加一个<key,value>键值对时,会先通过hashcode算法根据key计算出其哈希值,一般情况适用String字符串用作key因为String
为final修饰,创建出的内存地址不同,计算出的哈希值也不同。根据这个哈希值进行在数组中查找这个entity(包含了键值对,指向下一个节点的引用)所在的位置,找到后如果这个节点为空就新建节点,如果这个位置已经存在节点那就先判断key是否相等,则判断key和你put进来的key是否相等(注意相等的判定:hash值相等且equal相等),如果相等,那么直接更新其值value,也就是我们常见的覆盖旧value操作,如果旧value为null,则直接将null值设置为你传进来的value值,如果不相等(此处不介绍LinkedHashMap)则去以遍历的方式寻找这个节点的next节点,如果和这个链表的每个节点的next节点都不相等,则在链表的最后一个Node节点
后创建新节点。如果其中判定有一个相等,那么进行覆盖值并返回旧值操作。

解决hash冲突:
开放定址法: 当发生地址冲突时,按照某种方法继续探测哈希表中的其他存储单元,直到找到空位置为止。
再哈希法: 当发生哈希冲突时使用另一个哈希函数计算地址值,直到冲突不再发生。这种方法不易产生聚集,但是增加计算时间,同时需要准备许多哈希函数。
链地址法: 将所有哈希值相同的Key通过链表存储。key按顺序插入到链表中
建立公共溢出区:采用一个溢出表存储产生冲突的关键字。如果公共溢出区还产生冲突,再采用处理冲突方法处理。
java中的hashmap采用的是链地址法,就是如果hash值相同,就是将相同hash值的对象组织成一个链表放在hash值对应的槽位
Hashtable
Hashtable已经被弃用的一个类,性能比较低,它有一些自己的特点,不知道你发现没有,它不符合大小驼峰命名规则,这点很讨厌。
1、Hashtable的方法几乎都是同步的,都有synchronized关键字修饰,因此和HashMap相比,它是线程安全的。public synchronized V put(K key, V value) {…}
2、Hashtable中key-value的映射,key和value 都是不允许为null的,如果为null了呢?对不起,空指针异常抛出。
3、Hashtable在计算节点元素在哈希表中的位置使用的算法稍有区别,它有它的好处,但和HashMap的算法比起来明显性能低一些。
4、Hashtable的扩容是原来容量的二倍加1(2n+1),源码参考:int newCapacity = (oldCapacity << 1) + 1;

四、HashMap和Hashtable有哪些主要区别呢?
1、HashMap是继承自AbstractMap类,而HashTable是继承自Dictionary类。不过它们都实现了同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口。
2、Hashtable比HashMap多提供了elments() 和contains() 两个方法。
3、HashMap的key-value支持key-value,null-null,key-null,null-value四种。而Hashtable只支持key-value一种(即key和value都不为null这种形式)。既然HashMap支持带有null的形式,那么在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断,因为使用get的时候,当返回null时,你无法判断到底是不存在这个key,还是这个key就是null,还是key存在但value是null。
4、线程安全性不同,HashMap的方法都没有使用synchronized关键字修饰,都是非线程安全的,而Hashtable的方法几乎
都是被synchronized关键字修饰的。但是,当我们需要HashMap是线程安全的时,怎么办呢?我们可以通过Collections.synchronizedMap(hashMap)来进行处理,亦或者我们使用线程安全的ConcurrentHashMap。ConcurrentHashMap虽然也是线程安全的,但是它的效率比Hashtable要高好多倍。因为ConcurrentHashMap使用了分段锁,并不对整个数据进行锁定。
5、初始容量大小和每次扩充容量大小的不同
Hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。
6、计算hash值的方法不同
为了得到元素的位置,首先需要根据元素的 KEY计算出一个hash值,然后再用这个hash值来计算得到最终的位置。
Hashtable直接使用对象的hashCode。hashCode是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值。然后再使用除留余数发来获得最终的位置。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值