java集合

125 阅读3分钟

1. Arraylist 与 LinkedList 异同

1. 是否线程安全: 都不能保证线程安全
2. 底层数据结构: 一个是数组,一个是双向循环链表
3. 插入和删除是否受位置影响:
4. 是否支持快速随机访问: array支持
5. 内存空间占用: ArrayList的空间浪费主要是结尾要预留一定空间,LinkedList的空间花费是每个元素多要保存后继、前驱和数据

使用场景:

1、如果对各个索引元素进行大量的存储或删除操作,ArrayList要优于LinkedList

2、如果主要对列表进行循环,并且循环时进入插入或者删除操作,LinkedList要优于ArrayList

2. ArrayList 与 Vector 区别

都是List的实现类,底层用Object[]实现, vector是线程安全的

3. HashMap的底层实现

jdk1.8之前

JDK1.8之前是数组➕链表实现,链表主要是解决哈希冲突。如果定位到的数据位置,不含有链表,那么查找、添加等操作很快,O(1);如果含有链表,对于添加操作,O(1)只需要把元素放到链表头部,查找的时候遍历链表,通过key对象的equals方法注意对比查找。

image.png

jdk1.8以后

主要是解决冲突发生变化,当链表长度大于阈值(默认8),将链表转化为红黑树,减少搜索时间。

4. HashMap和Hashtable的区别

  • 线程安全: HashMap不是线程安全的,Hashtable是线程安全的,用synchronized修饰
  • 效率: HashMap效率更高,Hashtable基本被淘汰,很少使用了
  • 对于NullKey和NullValue: HashMap支持一个NulKey,多个NullValue,Hashtable不允许
  • 初始化量的大小和每次扩容量的大小: ①创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小
  • 底层数据结构: 超过阈值转化为红黑树

5. HashMap的长度为什么是2的幂次方

尽量把数据分配均匀,存取高效 。这个实现就是把数据存储到哪个链表/红黑树的算法。

我们首先可能会想到采用%取余的操作来实现。但是,重点来了: “取余(%)操作中如果除数是2的幂次则等价于与其除数减一的与(&)操作(也就是说 hash%length==hash&(length-1)的前提是 length 是2的 n 次方;)。” 并且 采用二进制位操作 &,相对于%能够提高运算效率,这就解释了 HashMap 的长度为什么是2的幂次方

6. HashSet 和 HashMap 区别

实现上: 一个实现了Set 一个实现Map

功能上:HashMap是key-value,HashSet支持对象

hashcode: HashMap使用key计算HashCode,HashSet使用对象计算hashcode,对于两个对象来说,hashcode可能相同,就用equals方法判断相等性。如果两个对象不同的话,那么返回false。

速度效率: HashMap更快

7. ConcurrentHashMap 和 Hashtable 的区别

底层数据结构:JDK1.8之后ConcurrentHashMap和HashMap的结构一样,也会升级红黑树。而Hashtable是数据+链表。

线程安全: Hashtable是全表锁。

8. ConcurrentHashMap线程安全的具体实现方式/底层具体实现

JDK1.8以前

数据分为一段一段的存储,然后每一段数据加一把锁,

JDK1.8之后

取消了Segment分段锁,采用CAS和synchronized来保证并发安全。数据结构跟HashMap1.8的结构类似,数组+链表/红黑二叉树

9. 集合框架底层数据结构总结

image.png

10、Object中的hashcode和equals问题

重写equals时为什么要重写hashcode

juejin.cn/post/703725…