Java基础

1.hashMap底层数据结构

JDK1.7及之前:entry数组+双向链表
JDK1.8:数组+链表+红黑树
hashMap默认数值

数组长度为16,可以在new hashMap的时候指定数组长度,这样会生成一个长度为大于输入参数的最小的2的整数次幂的entry数组;
load_factor为3/4;

put方法根据key的hash值来决定将<key, value>这个entry放在哪个位置:

entry的index = hash(key) & (n - 1),其中n是entry数组的长度。
其实这个式子就是在取模,之所以不用hash(key)%n,是因为取模的效率太低了。hash(key) & (n - 1)等价于取模,当且仅当n为2的整数次幂,所以hashMap要求数组长度为2 的整数次幂

当hashMap中的元素越来越多的时候,hash冲突是难以避免的,hashMap采用的是链地址法来避免hash冲突,即相同index的entry以链表的形式共存。

链表太长会影响效率,所以在jdk1.8,当链表的长度达到了8及以上,链表就升级成为红黑树。其查询/插入效率从O(n)变为O(logn)

为什么要等长度为8才升级呢?

一方面,链表长度太短,根本没必要升级为红黑树,因为从查询效率上来讲,他们差不多,而维护一棵红黑树是需要代价的,所以长度很短无需升级;
另一方面,长度为8的时候,红黑树的平均查找长度为3,如果继续使用链表,平均查找长度为8/2=4,这时候才有了真正的提升。

jdk源码中的注释解释道:hashMap元素的到来满足泊松分布,根据泊松分布计算概率,链表长度为8的概率为0.00000006,其概率相当的小。

2.JAVA集合的面经

点击查看

3.CopyOnWriteArrayList

点击查看

4.两个对象怎么进行比较?hashCode和equals的区别?

先比较hashCode,若两个对象的hashCode不相等,那么两个对象一定不相等;否则再用equals进行比较。
为什么不直接用equals进行比较?
有一个集合,里面有若干对象,现在有一个新加入的对象,要求判断新来的对象与是否存在于集合中,如果用equals得一个一个比较。而使用hashMap的思想,根据hashCode分桶,先比较hashCode,再用equals比较,大大提高效率。

5.序列化

点击查看

6.final关键字的用法?final两种重排序规则?

1.用在class,表示类不能被继承;
2.用在method,表示方法不能被重写;
3.用在变量,有两种情况,一是用在基础变量,则该变量对应的值不能改变;二是用在引用变量,则该变量引用的地址不能变,但他引用的对象的属性可以改变。

1、在构造函数内对一个 final 域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。原理是在写final域后插入storestore内存屏障
2、初次读一个包含 final 域的对象的引用,与随后初次读这个 final 域,这两个操作之间不能重排序。原理是在读final域前插入loadload内存屏障

7.Object类中的方法(待完善)

8.HashMap的put方法和HashMap的扩容过程

put:
在这里插入图片描述
resize:
当插入一个新entry时,entry数大于阈值(capacity*load factor)的时候,就会触发扩容

  1. 判断当前entry数组的长度是否达到了MAXIMUM_CAPACITY,如果达到了,就不扩容了,直接返回;否则,去第2步;
  2. 初始化一个长度为当前entry数组长度2倍的新数组;
  3. 遍历entry数组的每个entry,如果这个entry是链表的头节点,且jdk版本是1.7及之前,去第4步;如果jdk版本是1.8及以后,去第五步;如果当前entry是红黑树的根节点,去第六步;
  4. 把当前链表每个元素从头到尾的头插到新数组中,最后去第7步;
  5. 根据元素在新entry数组中的位置要么是当前index,要么是index+old_entry_length,可以把这个链表拆成两个链表:index不变的,或index+old_entry_length的;然后把这二者各自插入新数组,最后去第7步;
  6. 同理,红黑树的节点也分为两类,一类index不变,一类index+old_entry_length,每一类要根据其元素个数是否超过8,来决定将其变成链表或是继续保留红黑树结构,插入新数组,最后去第7步;
  7. end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值