HashCode和HashMap

HashCode和HashMap

1.HashCode

java.lang.Object类中有两个非常重要的方法:

public boolean equals(Object obj)

public int hashCode()

Object类是类继承结构的基础,所以是每一个类的父类。所有的对象,包括数组,都实现了在Object类中定义的方法。

equals()方法是用来判断其他的对象是否和该对象相等.

equals()方法在object类中定义如下:

public boolean equals(Object obj) {  
    return (this == obj);  
}  

很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是我们知道,String 、Math、Integer、Double等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法。

hashcode() 方法

hashCode()方法给对象返回一个hash code值。这个方法被用于hash tables,例如HashMap。

简而言之,在集合查找时,hashcode能大大降低对象比较次数,提高查找效率!

Java对象的eqauls方法和hashCode方法是这样规定的:

1、相等相同)的对象必须具有相等的哈希码(或者散列码)。

2、如果两个对象的hashCode相同,它们并不一定相同。

Hashset、Hashmap、Hashtable与hashcode()和equals()的密切关系

  • Hashset
    • 在hashset中不允许出现重复对象,元素的位置也是不确定的
    • 1.判断两个对象的hashCode是否相等 如果不相等,认为两个对象也不相等,如果相等,转入2
    • 2.判断两个对象用equals运算是否相等

2.HashMap

哈希桶 基于int hashCode实现
  • 核心是基于哈希值的桶和链表
  • O(1)的平均查找、插入、删除时间
  • 将元素映射成hash值
  • 底层是数组,数值查找值是常数时间,O(1)
  • 多个元素hash值相同,数据发生了碰撞,会有链表。 哈希值的碰撞是致命缺陷。
Java7 经典实现

hashcode->(0,n-1)

  • 取模
    • 负数取模是负数,无法存
    • 速度较慢
  • 为什么初始化是16,扩容是两倍。按位与,只有长度是2的n次方,只有len-1之后才可以是1111,按位与之后才可以拿到数组下标,而且分布均匀。

resize里的问题根源

java7 hashmap的问题

  • hashmap死锁,线程不安全。经典的数组+链表。同时入桶的话,会产生环链表。所以是线程不安全的。
  • String有可能hashcode相同,所以存入hashmap的时候产生链表,非常慢。伪造恶意请求引发Dos错误。
  • jdk1.7中,如果是String,则用新的hash算法H
java8 hashmap的改进

treeify 8 阈值

hash算法

  • 高位不同,低位相同
  • 异或不进位的加法
  • 线程不安全是由于扩容问题。
  • newIndex 要么相等,要么最高位加1.重新计算hash值就是拆分成两个新的链表。重新复制到新的hash桶里
  • resize效率非常低。Resize效率很低,因为每次都要
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值