您的位置:首页 > 其它

equals源码分析和hashcode关联(会介绍HashSet、HashMap源码)

2019-01-14 16:32 127 查看

今天早上小熙想了下equals的用法和特殊情况,就想验证下字符a和字符串a是否相等,又为什么呢?

小熙的环境是:idea、jdk1.8

1. 讲述equals,以及其源码

  1. 案例代码比较

    如图:

    虽然小熙知道结果是false,但是小熙却不知道所以然,所以查了下源。

  2. equals源码

    (1)equals其实是Object中就有的方法(引用了等于号),其他子类的比较只不过是重写equals方法而已。

    如图:

    (2)String类中重写equals方法的源码。

    如下图(有详细解释):

    关于value值:

    (3)小结

    好了经过小熙上面的源码分析,我们可以知道 “a”(字符串a)‘a’(字符a) 因为String类型重写的equals方法的第三步,判断出字符类型并不属于字符串类型,所以比较返回的是false,即不相等。

    (4)附上一张案例对象中,重写equals方法的图片

    和String类的重写类似,首先判断是否是同一个对象,其次再判断传入对象是否为空,加载类文件是否不相等,最后根据Objects中的equals方法判断值是否相等。这就是案例对象重写equals判断值是否相等的过程了。

2. equals和hashcode的关联(会介绍HashSet、HashMap源码)

  1. 其实hashcode方法也是object的,我们首先来看下在object中的源码:

    由上图可以看出hashcode是java的本地方法,其调用的C语言的代码,用来打印对象的地址值。

  2. 那可能有小伙伴就要问这和euqals有什么关系呢 (下面先介绍下HashSet、HashMap源码,不喜欢的可直接跳到第五条)

    答:
    (1)说道他们的关联,这就主要涉及到HashSet的数据结构和原理了,也是面试常问的问题。HashSet的底层其实是HashMap实现的(不清楚的小伙伴可以去查查,这里不再赘述了)。那HashMap的底层又是什么呢?
    (2)其实HashMap的底层是动态数组和链表组成,而链表又是由数据和模拟指针(引用)组成(其实在java中数据结构最基础的结构就两种,一种是数组,另一种就是模拟指针了(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体)。
    (3)那这里为什么是动态数组呢,因为HashMap有扩容机制,这与动态数组息息相关。其动态数组初始化默认长度是16,负载因子是0.75(也就是说当长度为12(16 x 0.75 = 12)的时候就要进行扩容了,为了防止存储长度不够),而其扩容后大小为之前大小的两倍,即第二次大小为32。
    (4)注意:1.8中添加了红黑树,当链表长度超过8的时候转为红黑树(8是根据泊松分布计算得出,有兴趣可以查查),并且添加新元素在链表的尾部,不会出现死循环。而1.7没有加入红黑树,新添加的元素在链表的头部,会出现死循环。
    (5)为了方便下面的讲解,所以了深入了下HashSet、HashMap源码。在HashMap存入数据的时候首先根据他的key计算其hashcode值,确定他在数组中的位置,如果数组的该位置上没有其他元素则直接添加,如果数组的该位置上已经存放有其他元素了,则调用equals判断值是否相同(只有hashcode值和equals判断都相同时才会计为e),记为e覆盖旧值 (这就是去重的原理,为什么要重写hashCode和equals也是他们的关联) ,如果不相同那么在这个位置上的元素将以链表的形式存放,新加入的放在链尾,最先加入的放在链头(当链表长度超过8的时候转为红黑树)。

好了以上就是小熙分享的内容了,如有出入还请指出哦。如果有问题,也可以点击小熙的头像获取联系方式和小熙联系哟。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: