equals() 和 == 的区别,为什么重新equal要重写hashCode?
==是运算符,equals()来自于Object类定义的一个方法
==可以用于基本数据类型和引用数据类型
equals()只能用于引用类型
==号两端如果是基本数据类型,就是判断值是否相同
equals在重写后,是判断两个对象的属性值是否相同
equals如果不重写,其实就是==
重写equals可以让我们自己定义判断两个对象是否相同的条件
Object中定义的hashcode方法生成的哈希码能保证同一个类的对象的哈希码一定是不同的
当eqauls返回为true,我们在逻辑上可以认为是同一个对象,但是查看哈希码,发现哈希码不同,和equals方法返回的结果违背
Object中定义的hashcode方法生成的哈希码跟对象的本身属性是无关的
重新hashcode之后,我们可以自定义哈希码的生成规则,可以通过对象的属性值计算出哈希码
HashMap中,借助equals和hashcode方法来完成数据的存储
将根据对象的内容查询转换为根据索引的查询:之前按照排序顺序进行搜索,之后可以按照对象中的属性值确定哈希值,根据哈希值确定位置
hashmap在1.8中做了哪些优化?
数据结构:
在Java1.7中,HashMap的数据结构为数组+单向链表。Java1.8中变成了数组+单向链表+红黑树
链表插入节点的方式:
在Java1.7中,插入链表节点使用头插法。Java1.8中变成了尾插法。
hash函数:
Java1.8的hash()中,将hash值高位(前16位)参与到取模运算中,使得计算结果不确定性增强,降低发生哈希碰撞的概率
扩容优化:
JDK1.7会重新计算每个元素的哈希值
JDK1.8中有扩容因子(0.75),当前有值所占用的空间/总空间=0.75时,总长度会扩大为原来的2倍
hashmap线程安全的方式?
方法一:
通过Collections.synchronizedMap()来封装所有不安全的HashMap的方法,所有方法都加锁,会降低效率
方法二:
重新写了HashMap,把HashMap拆分成了多个独立的块,这样在高并发下减少了锁冲突问题
hashmap为什么用红黑树不用AVL树?
AVL树:在AVL树中任何节点的两个子树的高度最大差别为1;若超过1,则会进行树旋转
红黑树:红黑树从根到叶子的最长路径不会超过最短路径的2倍
AVL树对平衡度较高,会导致调整频率变高,适合查询多,增/删少的场景
红黑树对平衡度要求低,调整频率低,适合增/删频繁的操作操作
简述一下Java运行时数据区
sleep与wait的区别
①sleep方法属于Thread类,而wait方法属于Object类
②sleep方法导致程序暂停执行时间,让出cpu,但他的监控状态依然保持,当指定的时间到了会自动恢复运行状态,在调用sleep方法过程中,线程不会释放对象锁
③当调用wait方法时,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify方法后,本线程才进入对象锁定池准备获取对象锁进入运行状态