Java集合知识点整理

Java集合知识点整理

java.lang

  • Collection接口
    • List接口
    • Set接口
  • Map接口

image-20220301163305657

Collection

List

  • 重复
  • 有序
1 ArrayList
  • List接口的主要实现类,底层用数组实现
  • 优点
    • 访问速度快
  • 缺点
    • 插入和删除开销大:增加和删除元素时,需要对整个数组进行遍历、定位和移动
    • 线程不安全

源码分析

  • JDK7

    • 创建

      • 底层创建一个长度为10的数组
    • 扩容

      • 设置新的存储空间为原来的1.5倍

        • 如果新存储空间仍然不够,则将要求的最小存储空间设置成新存储空间
      • 将原数组里的元素复制到新数组里

            private void grow(int minCapacity) {
                // overflow-conscious code
                int oldCapacity = elementData.length;
                int newCapacity = oldCapacity + (oldCapacity >> 1); //设置新的存储能力为原来的1.5倍
                if (newCapacity - minCapacity < 0) //扩容之后仍小于最低存储要求minCapacity
                    newCapacity = minCapacity;
                if (newCapacity - MAX_ARRAY_SIZE > 0) //private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
                    newCapacity = hugeCapacity(minCapacity);
                // minCapacity is usually close to size, so this is a win:
                elementData = Arrays.copyOf(elementData, newCapacity);
            }
        
  • JDK8

    • 创建
      • 初始时,底层数组的容量为0,当添加第一个元素时,才将数组容量设置为10
    • 扩容:和JDK7类似
2 LinkedList
  • 用双向链表存储元素
  • 优点:
    • 插入和删除数据快
  • 缺点:
    • 遍历和查找慢
    • 线程不安全
3 Vector
  • 底层用数组实现

  • 初始化时,默认容量为10

  • 扩容时,如果增量>0,则新容量为旧容量+增量;否则,新容量为原来的2倍。最后将数组里的值,复制到新数组里

    • 如果新容量不够,则以要求的容量为新容量
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    
  • 优点

    • 线程安全的,同一时间只能有一个线程写Vector
  • 缺点

    • 访问速度慢

Set

  • 无序
    • 无序不代表没有顺序,而是不像数组一样按索引值顺序添加的,set是由HashCode来决定存储位置的
  • 不可以重复
1 HashSet
  • Set接口的主要实现类,是线程不安全的

  • 可以存储null值

  • 添加

    • 当向HashSet添加元素a时,会调用HashCode()方法计算元素a的哈希值

    • 然后通过a的哈希值根据某种算法获得a的索引位置

      • 如果索引位置处没有元素,则元素a添加成功

      • 如果索引位置处有元素b,则a和b通过equals()方法比较

        • 两值相等,则添加失败

        • 两值不等,则添加成功

          旧元素”七上八下“:jdk7新元素放到数组,指向旧元素;jdk8旧元素指向新元素

  • 扩容

    image-20220301185528552

2 LinkedHashSet
  • 添加数据的时候,会添加两个引用,引向前一个数据和后一个数据
  • 底层用LinkedHashMap实现
3 TreeSet
  • 要求添加的必须是同一个类的对象
  • 会对添加的元素排序

Map

  • Entry表示一对key和value
  • Entry由Set结构保存,是无序、不可重复的
1 HashMap
  • Map的主要实现类

  • 可以存放null的key和value,但最多只能允许一条key为null的entry,可以有多条value为null的entry

    map.put(null, null);
    
  • 线程不安全

    • 但是可以使用synchronizedMap()方法和ConcurrentHashMap()方法使其变成线程安全的

JDK7

  • 底层用数组+链表实现的,数组默认容量为16
  • 插入数据时,首先计算key的哈希值,然后找到数组相应要存放的位置
    • 如果该位置是空的,则直接插入即可
    • 如果该位置是非空的,则先比较key和位置上所有key值的哈希值
      • 如果哈希值不相等,则插入key-value
      • 如果哈希值相等,则需要调用key的equals方法和位置上存在的key1进行比较
        • 如果相等,则将key1的value1替换成新的value
        • 如果不相等,则以链表形式插入新的key-value

JDK8

  • 底层用数组+链表+红黑树实现,初始化时,数组容量为0

    • 当第一次put数据时,初始化16容量的数组
  • 当链表元素>8且哈希表长度>MIN_TREEIFY_CAPACITY(64),则转换成红黑树

    if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
    	treeifyBin(tab, hash);
    break;
    
    if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
        resize();
    else if ((e = tab[index = (n - 1) & hash]) != null) {
        ...
    }
    

扩容

  • 默认容量为16,负载因子为0.75

    • 当超过容量*负载因子时,就扩容,扩容成原来的两倍
  • 为什么负载因子为0.75?

    • Ideally, under random hashCodes, the frequency of nodes in bins follows a Poisson distribution.
    • 负载因子是0.75的时候,空间利用率比较高,而且避免了相当多的Hash冲突,使得底层的链表或者是红黑树的高度比较低,提升了空间效率。
2 TreeMap
  • 插入的key必须是同一个类的对象
  • 会根据key值进行排序
  • 底层用红黑树实现
3 HashTable
  • 线程安全的,效率低
  • 不能存储值为null的key和value
  • 有一个子类Property,用于处理配置文件

ibution.

  • 负载因子是0.75的时候,空间利用率比较高,而且避免了相当多的Hash冲突,使得底层的链表或者是红黑树的高度比较低,提升了空间效率。
2 TreeMap
  • 插入的key必须是同一个类的对象
  • 会根据key值进行排序
  • 底层用红黑树实现
3 HashTable
  • 线程安全的,效率低
  • 不能存储值为null的key和value
  • 有一个子类Property,用于处理配置文件
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我无法回答关于2023年的问题,因为我无法提供未来的信息。但是,如果你对Java基础知识点有兴趣,我可以为你提供一些相关的信息。Java基础知识点包括数据类型、变量、运算符、控制流程、数组、字符串、面向对象编程等。你可以参考Java基础教程系列,其中包含了Java基础知识点Java8新特性、Java集合Java多线程等内容,可以帮助你轻松学习Java编程。\[1\]另外,Javac是Java编译器程序的一部分,负责将Java源代码编译成字节码文件,也就是class文件,供Java虚拟机(JVM)执行。\[2\]Java分为三个体系,分别是Java SE(标准版)、Java EE(企业版)和Java ME(微型版),每个体系都有不同的用途和应用领域。\[3\]希望这些信息对你有帮助! #### 引用[.reference_title] - *1* [java基础知识点](https://blog.csdn.net/guorui_java/article/details/120317300)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Java基础知识点整理,推荐收藏!](https://blog.csdn.net/weixin_42599558/article/details/114148399)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值