HashMap和HashTable

本文详细探讨了HashMap和HashTable的数据结构、工作原理及性能特点,包括散列桶、链表、红黑树转换机制,以及它们之间的关键差异,如线程安全性、默认容量和效率对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. HashMap

 

HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射

HashMap采用了数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和链表的寻址修改

HashMap是非synchronized,所以HashMap很快

HashMap可以接受null键和值,而Hashtable则不能(原因就是equlas()方法需要对象,因为HashMap是后出的API经过处理才可以)

 

  1. HashMap的工作原理是什么?

 

HashMap是基于hashing的原理,我们使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,计算并返回的hashCode是用于找到Map数组的bucket位置来储存Node 对象。这里关键点在于指出,HashMap是在bucket中储存键对象和值对象,作为Map.Node 。

 

 

  • 以下是HashMap初始化 ,简单模拟数据结构

  • 以下是具体的put过程(JDK1.8版)

1、对Key求Hash值,然后再计算下标

2、如果没有碰撞,直接放入桶中(碰撞的意思是计算得到的Hash值相同,需要放到同一个bucket中)

3、如果碰撞了,以链表的方式链接到后面

4、如果链表长度超过阀值( TREEIFY THRESHOLD==8),就把链表转成红黑树,链表长度低于6,就把红黑树转回链表

5、如果节点已经存在就替换旧值

6、如果桶满了(容量16*加载因子0.75),就需要 resize(扩容2倍后重排)

 

  • 以下是具体get过程(考虑特殊情况如果两个键的hashcode相同,你如何获取值对象?)

当我们调用get()方法,HashMap会使用键对象的hashcode找到bucket位置,找到bucket位置之后,会调用keys.equals()方法去找到链表中正确的节点,最终找到要找的值对象。

 

 

  1. HashTable

 

数组 + 链表方式存储

默认容量: 11(质数 为宜)

put:

索引计算 : (key.hashCode() & 0x7FFFFFFF)% table.length

若在链表中找到了,则替换旧值,若未找到则继续

当总元素个数超过容量*加载因子时,扩容为原来 2 倍并重新散列。

将新元素加到链表头部

 

对修改 Hashtable 内部共享数据的方法添加了 synchronized,保证线程安全。

 

  1. HashMap ,HashTable 区别

 

默认容量不同。扩容不同

线程安全性,HashTable 安全 

效率不同 HashTable 要慢因为加锁

 

  1. String 和StringBuffer的区别

 

JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用StringBuffers来动态构造字符数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值