码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Java基础:集合类之ArrayList、HashMap简介


    Java基础:集合类之ArrayList,HashSet,HashMap

    • 1、ArrayList
      • 1.1 ArrayList的底层数据结构是什么?初始容量是多少?
      • 1.2 ArrayList添加元素的过程是什么?会用到哪些方法?
      • 1.3 ArrayList是线程安全的么?保证list线程安全的方法有哪些?
      • 1.4 什么情况下会使用ArrayList,什么情况下会使用LinkedList?
    • 2、HashMap
      • 2.1 HashMap的底层数据结构是什么?初始容量是多少?
      • 2.2 HashMap添加元素的过程是什么?会用到哪些方法?
        • 2.2.1 如何计算该key在数组中的位置?
        • 2.2.2 HashMap添加元素的过程?
      • 2.3 HashMap是线程安全的么?保证map线程安全的方法有哪些?

    1、ArrayList

    1.1 ArrayList的底层数据结构是什么?初始容量是多少?

    ArrayList的底层数据结构是一个object类型的数组。

    如果不指定初始容量的话,默认为长度为10的空数组。
    在这里插入图片描述

    1.2 ArrayList添加元素的过程是什么?会用到哪些方法?

    答:
    1、确保arraylist容量满足大小:ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
      1.1 计算所需最小容量minCapacity:当到达最大容量后,更新为最新最小所需容量
      1.2 确保容量满足所需大小:如果当前所需最小容量比当前元素总数多,那么需要扩容
        1.2.1 新容量为原容量的1.5倍:newCapacity = oldCapacity + (oldCapacity >> 1);
        1.2.2 通过Arrays.copyOf复制原数组:
           elementData = Arrays.copyOf(elementData, newCapacity);
    2、数组添加新元素:elementData[size++] = e;
    在这里插入图片描述

    在这里插入图片描述

    1.3 ArrayList是线程安全的么?保证list线程安全的方法有哪些?

    arraylist不是线程安全的。
    1)使用Vector替代
    2)使用Collections包装:Collections.synchronizedList(new ArrayList<>())
    3)使用CopyOnWriteArrayList替代

    1.4 什么情况下会使用ArrayList,什么情况下会使用LinkedList?

    由于ArrayList使用add方法时,会频繁调用System的arraycopy方法进行扩容,因此如果该list是以查询为主的话,使用ArrayList;

    如果增删多的话,就不适合使用arrayList了,此时就可以使用LinkedList了,因为它的增删操作的时间复杂度为O(1),而ArrayList的时间复杂度为O(n),n为ArrayList的长度。

    2、HashMap

    2.1 HashMap的底层数据结构是什么?初始容量是多少?

    jdk1.8之后,HashMap采用:数组 + 链表/红黑树 的方式来存储数据。

    HashMap的底层数据结构是node类型的数组:transient Node[] table。默认初始容量大小为16,默认扩容因子是0.75。
    在这里插入图片描述
    在这里插入图片描述

    2.2 HashMap添加元素的过程是什么?会用到哪些方法?

    2.2.1 如何计算该key在数组中的位置?

    计算该key所在数组的位置主要有3个步骤:

    1. 通过key.hashCode()获取key的hashcode;
    2. 通过(h = key.hashCode()) ^ (h >>> 16)进行高16位的位运算;
    3. 通过(n - 1) & hash对计算的hash值取模运算,得到节点插入的数组所在位置。

    说明:
    1)为什么要将hashcode右移16位再进行异或运算?
    这样做的好处是,可以将hashcode高位和低位的值进行混合做异或运算。这样,低位的信息中加入了高位的信息,等于说计算下标时把hash的高16位也参与进来了,掺杂的元素多了,那么生成的hash值的随机性会增大,减少了hash碰撞。
    2)为什么HashMap的长度一般是2^n?
    当length总是2的n次方时,h& (length-1)运算等价于对length取模,也就是h%length,但是&比%具有更高的效率。
    在这里插入图片描述

    2.2.2 HashMap添加元素的过程?

    HashMap的添加元素的过程:

    1. 判断键值对数组table[i]是否为空/null,是则执行resize()扩容
    2. 根据键key计算hash值得到插入数组的索引i,如果tab[i]== null则直接插入,执行第6步;如果tab[i] != null,执行第3步
    3. 判断tab[i]的第一个元素与插入元素key的hashcode&equals是否相等,相等则覆盖,否则执行第4步
    4. 判断tab[i]是否是红黑树节点TreeNode,是则在红黑树中插入节点,否则执行第5步
    5. 遍历tab[i]判断链表是否大于8,大于8则可能转成红黑树(要求数组同时需要大于64),满足则在红黑树中插入节点;否则在链表中插入;在遍历链表的过程中如果存在key的hashcode&equals相等则替换即可
    6. 插入成功,判断hashmap的size是否超过threshold的值,超过则扩容

    在这里插入图片描述

    2.3 HashMap是线程安全的么?保证map线程安全的方法有哪些?

    1)使用HashTable替代
    2)使用Collections包装:Collections.synchronizedMap(new HashMap());
    3)使用ConcurrentHashMap替代

  • 相关阅读:
    D. Chip Move(DP,优化时间和空间)
    Vue 3 框架
    【CSS3】CSS3 动画 ⑥ ( 动画属性示例 | 精灵图帧动画效果实现 )
    〔004〕Java 基础之数组、方法
    生成带干扰线的验证码
    ubuntu安装freeswitch 1.10.10
    JSON.stringify()与Qs.stringify()区别 应用场景
    pyinstaller打包教程(pycharm)
    电脑重装系统后内存占用高怎么解决?
    12个MySQL慢查询的原因分析
  • 原文地址:https://blog.csdn.net/xueping_wu/article/details/124623065
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号