Java 容器面试知识点

List Set Map 的区别

List和Set继承同一个接口Collection。
List中的元素是有序的可重复的,ArrayList默认初始化为容量为10的空列表,没有负载因子。
Set 中的元素是无序不可重复的,HashSet默认初始化容量为16,负载因子为0.75。
Map 中key是无序不可重复的,value是无序可重复的。

ArrayList和LinkedList的区别

ArrayList底层是数组结构,支持快速的随机访问,但是中间增删效率低,因为涉及到数组的拷贝。
LinkedList底层是链表,不支持随机访问,增删速度快,因为只需要链表的断开和链接(每个元素都有上一个和下一个元素的地址)。

ArrayList的扩容

空构造器初始化时ArrayList是一个空数组,长度为0,在第一次执行add方法时,创建长度为10的数组,每次扩容时扩容原来的1.5倍。
计算方式如下:
在这里插入图片描述

HashSet的扩容

HashSet的底层是HashMap,
在这里插入图片描述
在这里插入图片描述

HashMap的原理

在这里插入图片描述

HashMap的创建

在jdk1.8以前:在构造方法中创建一个长度是16的Entry[]table的数组来存储数据。
在jdk1.8以后:在第一次调用put方法时创建一个长度16的数组Node[]table来存储数据

HashMap的添加

1.计算出在数组的位置。根据key计算hashCode值,用这个值和数组的长度-1进行与运算,得出在数组的索引。
2.如果在数组上这个位置没有数据,就将元素放到这个位置上,
如果这个位置上有数据,将key和这个位置上的所有数据遍历进行equals,如果都不相等,就将数据放到链表的尾部,如果有相等的,就将value值替换。

线程安全的容器

vectory,hashtable

vectory中的方法基本上都加了synchronized关键字实现线程安全,其他和ArrayList没有区别
hashtable的所有涉及到并发的方法的被synchroniced关键字修饰(即在方法加了同步锁),所以在并发情况下是线程安全的,但又因为被sysnchronized修饰所以性能没有hashmap好。

HashTable是通过同步锁线程安全的(和vector一样),每次扩容都是旧数组大小的两倍,如果超出最大容量则使用最大容量来进行扩容,在添加,修改、删除方面速度比较快,在查询方面需要进行遍历,此外,要尽量避免重新散列,因为重新散列会对性能有所影响。

Concurrent包中的类

ConcurrentHashMap
数组+链表改为数组+链表+红黑树
在这里插入图片描述
Put 操作的变化

1、根据 key 计算出 hashcode,然后开始遍历 table;
  2、判断是否需要初始化;
  3、f 即为当前 key 定位出的 Node,如果为空表示当前位置可以写入数据,利用 CAS 尝试写入,失败则自旋保证成功。
  4、如果当前位置的 hashcode == MOVED == -1,则需要进行扩容。
  5、如果都不满足,则利用 synchronized 锁写入数据。
  7、如果数量大于 TREEIFY_THRESHOLD 则要转换为红黑树。

Get 操作的变化

根据计算出来的 hashcode 寻址,如果就在桶上那么直接返回值。
  如果是红黑树那就按照树的方式获取值。
  都不满足那就按照链表的方式遍历获取值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值