集合
集合的本质:数组+数据结构
Collections工具类中为各个单列集合提供了Synchronize()方法, 保证了线程的安全
1.单列集合
1.1. list
无序,但是可以使用Collections的sort()方法进行排序
有索引,所以存储有序,可存储重复元素
1.1.1.ArrayList
底层是可变数组
1.1.2. LinkedList
底层是链表, 在链表每个节点的首尾放着前一个和后一个节点的地址值
1.1.3. Vector
线程安全,
1.2. Set
1.2.1. HashSet
hashset基础信息
-
①底层使用hash表存储(本质还是数组)
-
②默认初始容量16
-
③加载因子0.75
底层使用hash表
①hashset插入数据时,会先计算一个int 类型的hash值,
②然后和已存储的hash值进行比较, 若hash不一致则存储
③若hash值一致, 则比较实际, 实际值一致则不存储, 不一致则存储,
④比较实际值实际是调用hashCode()方法, 取决于是否重写hashCode()方法
1.2.2. TreeSet
树结构的排序规则需要开发人员自行编辑排序算法
TreeSet遵循树结构, 添加元素规则为红黑树规则,
红黑树简述:
-
①添加元素时, 遵循红黑规则
-
②每次添加会和各层级的节点进行比较, 然后根据大小排序放在左右边
-
③当某一个分支过长会重构树结构
1.2.1.1 Hash算法
HashSet采用Hash算法
hash算法:
hash算法会将
hash算法会将所有的数组内的值较为均匀的存入指定长度的容器(数组)中
1.2.2 哈希表
hash表是以键值对形式存放
①创建一个连续的数组,数组的索引是用来存储hash值,
②使用hash算法, 将插入的数值计算取hash值
③hash值是一个较小的int类型的整数, 所有的hash
④若hash表中有数据hash值为该值,则在hash表的数组中对应的索引占位,未占位的索引对应的值是null
⑤当校验hash值一致时会再校验实际值,来解决hash冲突,
⑥数据过多时,会触发加载因子,hash表会扩容,以此降低hash冲突
2.双列集合
3.集合的遍历
3.1. 迭代器(用于遍历collection集合)
①集合生成时会获得一个版本号,初始值为0;每次增删改集合,版本号++
②迭代器遍历集合时都会对集合生成一个镜像,
③生成一个镜像版本号,并将集合的版本号赋值给镜像版本号,
④每次对镜像进行改动之后,镜像版本号++,集合版本号++
⑤每次遍历之前(hasNext()方法)都会对镜像版本号和集合版本号进行==比较;true:继续遍历,false:抛出并发修改异常
⑥所以在iterator创建之后,遍历结束才能对集合进行本身修改,一旦对collection进行修改,则之前创建的iterator失效
⑦只能通过先修改镜像,后台默认修改集合,来控制集合版本号和镜像版本号一致
3.2. 增强for和foreach
内部原理是使用的迭代器, 同样释放掉迭代器之前不能对集合进行增删改操作