Java集合

集合:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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.53:   如果使用的是指定大小的构造器,则初始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 
    
 
    HashMapHashTable  的区别?
    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  
posted @ 2022-10-06 20:19  wode林夕  阅读(9)  评论(0编辑  收藏  举报  来源