集合:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M6fGWisy-1665058747947)(C:\Users\12926\AppData\Roaming\Typora\typora-user-images\1663550517921.png)]
集合可以保存任意对象,使用比较简便。
常用的方法:
add, remove, set(修改) ,get(返回) var code = “ea38806f-8854-4e27-9c65-66fd2353fdb7”
集合分为:
单列集合,双列集合
Collection
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7aY7UdFN-1665058747948)(C:\Users\12926\AppData\Roaming\Typora\typora-user-images\1663552222598.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NJxSSH5t-1665058747948)(C:\Users\12926\AppData\Roaming\Typora\typora-user-images\1663552205068.png)]
遍历集合:
Iterator<Object> iterator = list.iterator(); 迭代器 while (iterator.hasNext()) { Object next = iterator.next(); System.out.println(next); } for (Object list1 : list) { 增强for System.out.println(list1); } System.out.println("==============================================="); for (int i = 0; i < list.size(); i++) { for循环 System.out.println(list.get(i)); }
List 集合中的1元素是有序得(即添加顺序和取出顺序是一致的,且可重复)
LIst集合中每个元素都有都有对应的顺序索引,即支持索引
List 容器中的元素都对应一个整数型的序号,记载其在容器中的位置,可以根据序号存取容器中的元素
ArrayList :
可以加入null 空值
是由数组实现数据存储得
基本等同于Vectory,除了ArrayList是线程不安全得(它执行效率高),在多线程得情况下,不建议使用ArrayList
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rj87X0he-1665058747949)(C:\Users\12926\AppData\Roaming\Typora\typora-user-images\1663574937705.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U3KMjF7f-1665058747949)(C:\Users\12926\AppData\Roaming\Typora\typora-user-images\1663575011509.png)]
ArrayList扩容机制:
1: ArrayList 中维护了一个Object 类型的数组elementData (transient 表示属性不会被序列化 Object[] elementData) 可以理解为:刚开始创建集合时,内存为0 ,第一次添加数据之后,elementData扩容为10,第二次扩容到elementData 的1.5倍 , 扩容时,底层数组进行了一次复制: (elementData = Arrays.copyof(elementData,newCapacity)) 依次类推 2: 当创建ArrayList对象时,如果使用的时无参构造器,则初始elementData 容量为 0 ,第一次添加,则扩容elementData 为10,如需再次扩容,则扩容到elementData 为1.5倍 3: 如果使用的是指定大小的构造器,则初始elementData 容量为指定大小 ,如果需要扩容则直接扩容elementData 为1.5倍 会创建一个指定得elementData得数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PY6FeIhF-1665058747950)(C:\Users\12926\AppData\Roaming\Typora\typora-user-images\1663577820441.png)]
无参构造的集合时:
首先执行add方法,执行看是否需要扩容。在执行赋值。如果elementData 的大小不够,就会执行 grow() 扩容。
第一次扩容为10, modCount++ 记录集合修改的次数,
扩容使用的时Arrays.copyof()
Vector 扩容机制
带有synchronized 是线程安全的 ,底层都是可变数组
扩容机制: 如果是无参,默认扩容10,从第二次开始2倍扩容
如果指定大小,则每次指定按2倍扩容
LinkedList的底层结构:
底层实现了双向链表和双端队列特点
可以添加任意元素(元素可以重复),包括null
线程不安全,没有实现同步
Set接口
基本介绍:
1:无序(添加和取出的顺序不一致),没有索引
2:不允许有重复元素,所以最多只能包括一个null
HashSet 底层实际上是HashMap
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kcpq9EGN-1665058747951)(C:\Users\12926\AppData\Roaming\Typora\typora-user-images\1663596284609.png)]
hashset 不保证存放元素的顺序和取出的顺序一致:
Hashset的底层是hashMap ,HashMap底层是(数组,红黑树,链表)
Hashset的扩容机制:
1: HashSet 的底层是HashMap 2: hashSeT 在添加一个元素时,会首先 得到一个hash值,然后将hash值转为索引值 3: 找到存在数据的Table表,通过上一步得到的索引值,通过for 循环,依次和该链表的每一个元素匹配。这个索引位置是否以及存放的有元素,如果没有直接加入到table表中,如果有 调用equals 进行比较,如果相同,则弃用(执行break;跳出链表比较),如果不同,则以链表的方式添加到最后。 4: 在JAVA 8 中,如果一条链表的元素个等于默认 8 ,并且table 的大小超过64 .就会转化为红黑树 否则任然是采用数组的扩容机制 2倍扩容机制 源码: 首先执行的是一个构造器,然后是add() , 执行put() 方法(的hash(key)) 然后执行putval方法 第一次扩容到16 ,用加载因子0.75 x 16 = 12 当达到12 时 就要开始扩容 //根据key得到的hash 值,去计算该key 应该存放到table 表的哪个位置
分析HashSet 的扩容和转换成红黑树 第一次添加的时候table表的扩容到16,临界值:16 X 加载因子{default loadFactor}0.75 = 12 ,即达到12 时就会扩容到 16 x 2= 32 此时的临界值即为 36x 0.75 = 24 在JAVA8 中,如果一条链表的个数达到了8 ,并且table 表的大小超过 默认64 ,就会转换为红黑树 。否则就会仍然采用数组的扩容机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lNM6IiaR-1665058747952)(C:\Users\12926\AppData\Roaming\Typora\typora-user-images\1664004091906.png)]
LinkedHashSet
LinkedHashSet 是HashSet的子类。 底层是LinkedHashMap 底层是维护了一个数组+双向链表 不允许有重复元素 LinkedHashSet 是根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序(图),这使得元素看起来是以顺序保存的/
Map接口 JDK8
HashTable HashMap TreeMap HashMap 中的key不允许重复,values 可以重复。 key 可以为null Values 也可以为空 ,key 为null 只可以有一个values 为空可以有多个 常用String 类来作为key HashMap 和HashTable 的区别? HashMap没有实现线程同步,所以是线程不安全的
HaspMap 底层源码 (K,v)是一个Node 实现了Map.Entry<K,v> Jdk 7 以前是数组+链表 jdk 8 以后是数组+链表+红黑树
HashMap 扩容机制: 1:HashMap 底层是维护了一个Node 类型的数组table,它的初始值为null 2: 当创建完时,执行new HashMap ()构造器。将加载因子初始化为(loadFactor)0.75 3: 第一次添加的时候,会调用底层putVal() 。resize()扩容为16 ,他有一个临界值 : 16x 加载因子0.75 = 12 4:当添加key- val的时候,通过key的哈希值(hash(key))通过hash算法得到在table处的索引,然后判断该索引处是否有元素,如果没有元素直接添加,如果该索引处有元素,继续判断该元素的key 是否和准备加入的key相等,如果相等直接替换Val ; 如果发现不相等需要判断是是树结构还是链表结构。如果是树结构加入到树中 ,如果是链表首先通过key 判断是否存在数据,有就替换。没有就使用尾插法 插到链表尾部,如果发现内存不够,则需要进行扩容 使用resize()进行扩容 5: 以后在扩容,则需要扩容table 容量的原来的2倍 6:jdk 8 以后如果一条链表的个数超过8 以后,并且table数组的长度大于64 就会进化成红黑树
HashTable
hashTable 的键值都不能为空,否则会抛出空指针异常,hashTable 和hashMap的使用方法基本一样
hashTable 是线程安全的,hashMap是线程不安全的
1:底层有数组,大小为11
扩容机制为 :原本大小俩位 + 1
超过8 以后,并且table数组的长度大于64 就会进化成红黑树
#### HashTable hashTable 的键值都不能为空,否则会抛出空指针异常,hashTable 和hashMap的使用方法基本一样 hashTable 是线程安全的,hashMap是线程不安全的 1:底层有数组,大小为11 扩容机制为 :原本大小俩位 + 1 子类 properties