很多人搞不懂集合,尤其是在Map方面 ,我也不例外 ,索性把我的理解发布出来。大家多多指正
小伙伴们觉得有用的话,就动动发财的小手点个赞吧!!!!
首先要明确java中的集合是什么:
Java中的集合是一种用来存储和操作多个元素的数据结构。 Java提供了多种集合类,每种类都有不同的特点和用途。(这句没什么大用)
那么重点来了!
常用的集合类有:
- List(列表): 用于存储有序的元素列表,可以通过索引访问和修改元素,常用的实现类有ArrayList和LinkedList。
- Set(集): 用于存储无序的唯一元素,不允许重复元素的存在,常用的实现类有HashSet和TreeSet。
- Map(映射): 用于存储键值对(key-value)的数据,根据键来查找和操作值,常用的实现类有HashMap和TreeMap。
- Queue(队列): 用于存储一系列元素,并按照一定的规则进行添加和删除元素的操作,常用的实现类有LinkedList和PriorityQueue。
了解以上的知识之后呢 就进入正题了
java中的集合主要分文两类 :
- 单例集合Collection (单例集合包括 List 、Set、Queue)
- 多例集合Map (多例集合包括 Map)
附:应该有很多小伙伴不知道这个"Collection"怎么读是吧 偷偷告诉你读作"可来可神"
那么我们先从单例集合开始-->请看下图
所以单例集合就只有 List、Queue、Set 这三个
List: 允许存储重复的值 是按照插入的顺序存储的
Set: 存储不重复的数据 无序的
List里面的重点是ArrayList 和LinkedList、Vector
- ArrayList 底层是数组 查询快,增删慢 , 线程不安全
- LinkedList 底层数据结构是链表,查询慢,增删快, 线程不安全
- Vector 底层是数组 查询快,增删慢 , 线程安全
这里需要注意一个问题 ArrayList的原理
ArrayList 底层是动态数组实现的 它是先创建一个长度为10的数组 如果插入的数据超过十个 那么它就会创建一个新的数据 长度是原来的1.5倍 然后将原来数组中的数据拷贝到新数组中,所以如果存贮数据量比较大的时候,我们应该指定ArrayList的长度以避免多次扩容影响效率
Set里面的中重点是HashSet
HashSet: 底层数据结构是哈希表 (无序、唯一)
Queue: 不重要
以上就是单例集合 下面就是Map了!!!
你: "就这么一点?"
经验: "记那么多没有用!!"
那么Map 就相对比较复杂了 先看图
对! 没错Map就是有这么多
但是我们重点关注HashMap 下面以问答的方式描述
提问: HashMap的底层是什么结构?
答: 是数组+链表+红黑树 (附: 什么jdk7 jdk8的 谁会用jdk7以下的版本呢? 记它有什么用!)
提问: HashMap put的流程
答: 先看图
很复杂是吧 其实就是挺复杂的
其实HashMap的put操作就是根据hash值确定存储位置,处理冲突,插入数据,最后进行扩容。
1. 首先,根据要插入的key计算出它的hash值,这个hash值用于确定key在哈希表中的位置。
2. 然后,根据计算出的hash值,找到对应的桶,如果该桶为空,则说明这个位置没有发生冲突,直接将key-value插入到该桶中。
3. 如果发生了冲突,即在该桶中已经有其他的key-value存在,HashMap会使用链表或红黑树的数据结构来处理冲突。
- - 如果链表的长度小于8,则将新的key-value插入到链表的尾部。
- - 如果链表的长度等于8,则将链表转换为红黑树来存储数据,以提高查找效率。
- - 如果发生了红黑树的转换,且红黑树的节点数量超过了64,则会再次进行树的平衡操作。
4. 最后,插入完成后,如果需要扩容,即当前的元素数量达到了负载因子(默认为0.75)设置的阈值,HashMap会进行扩容操作,重新计算存储位置,以减少哈希冲突的概率。
以上只是一种简单的答案