Java集合(底层设计与实现)

news2024/11/30 20:46:59

Java集合(底层设计与实现)

集合体系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kzN1e0JP-1683732720294)(D:\图片\typora\image-20230508212938739.png)]
在这里插入图片描述

List接口

基本介绍

  • 元素有序(即添加顺序和取出顺序一致)、且可重复
  • 支持索引
  • 有下标,下标对应元素在容器中的位置

ArrayList

基本介绍:底层由数组实现;在多线程环境下不建议使用,由于没有加synchronized线程不安全,建议使用Vector。

  • 底层是维护一个Object类型的elementData数组
  • 当创建ArrayList对象时,如果使用的是一个无参构造器,则初始elementData数组容量为0;第一次添加元素,数组容量扩充为10;如需再次扩容,则扩容elementData数组容量1.5倍
  • 如果使用的是指定大小的构造器,则创建后的大小即为输入值,后续扩容是直接扩容1.5倍

核心代码:

/**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

Vector

基本介绍:底层由数组实现

  • 底层是维护一个Object类型的elementData数组
  • Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized
  • 构建时,如果是无参,默认容量是10,之后扩容,就按2倍扩容
  • 有参构建时,容量为输入的数,之后扩容,直接2倍扩容

核心代码:

/**
     * The maximum size of array to allocate.
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    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);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

LinkedList

基本介绍:LinkedList底层实现了一个双向链表和双端队列;线程不安全,没有实现线程同步

  • LinkedList底层维护一个双向链表
  • LinkedList中维护了两个属性,first和last,分别指向首节点和尾节点

ArrayList与LinkedList的比较

在这里插入图片描述

如何选择:

  • 查找操作多时,建议使用ArrayList
  • 修改操作多时,建有使用LinkedList

Set接口

基本介绍

  • 无序(添加顺序与取出顺序不一样),没有索引
  • 不允许有重复元素,所以最多包含一个null

HashSet

  • 底层为HashMap(HashMap的底层为 链表+数组+红黑树)
  • add方法返回一个boolean类型的结果,添加成功ture,失败(重复添加)为false

面试题

  • 同时添加两个new String("123"),一个添加成功,一个失败

扩容机制

  • 底层是HashMap
  • 添加元素时,先得到hash值,然后传换成索引值
  • 找到存储数据表table,看这个索引位置是否存在元素
  • 如果没有则加入
  • 如果有,调用equals比较,如果相同,就放弃添加,如果不同则添加到最后
  • 如果一条链表的元素数到达默认值,并且table的大小大于等于默认值,就会发生树化(红黑树)

核心代码

/**
     * Implements Map.put and related methods.
     *
     * @param hash hash for key
     * @param key the key
     * @param value the value to put
     * @param onlyIfAbsent if true, don't change existing value
     * @param evict if false, the table is in creation mode.
     * @return previous value, or null if none
     */
    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;								//定义辅助变量
        //table 就是 HashMap 的一个数组,类型是 Node[]
        //如果当前 table 是 null,或者大小 = 0
        //就扩容,到16个空间
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            // 判断 p 是否是一棵红黑树
            // 如果是一颗红黑树,就调用 putTreeVul, 来进行添加
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            // 如果table对应索引位置,已经是一个链表,就使用for循环比较
            // (1)依次和该链表的每一个节点上的元素比较,都不相同,则加入到该链表的最后
            //    注意,在将元素添加到链表后,立即判断 该链表是否已经达到8个结点,达到
           	//    则调用 treeifyBin() 对当前这个链表进行树化(红黑树)。
            //    注意,转换成红黑树以后,还要进行判断,当table表与链表的大小达到64时,
            //    才会树化,其余先将table进行扩容
            // (2)依次和该链表的每一个节点上的元素比较,如果有相同情况,就直接break
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/512033.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软考 软件设计师数据结构二笔记

查找基本概念 顺序查找 折半查找&#xff08;二分查找顺序存储 &#xff09; 查找一个数据先给他折中&#xff0c;看看要查找的是不是大于中间值如果大于前面的就不用查找了 l和r指向对应下标 二分查找补充 上图描述如何构造这般查找判定树&#xff0c;一般都是下取整 …

PDF怎么转Word?简单几步轻松操作

PDF格式是目前最为流行的电子文档格式之一。但是&#xff0c;当我们需要编辑或修改PDF文件时&#xff0c;通常需要将其转换为Word文档格式。在本文中&#xff0c;我们将介绍如何将PDF文件转换为Word文档&#xff0c;并且列举PDF和Word文档操作上的差异。 PDF转Word文档操作方法…

19 树表的查找

文章目录 二叉排序树(BST)查找操作二叉排序树的存储结构查找实现查找算法分析二叉排序树的平均查找长度 插入操作删除操作代码实现 平衡二叉树&#xff08;AVL&#xff09;插入&旋转操作插入操作四种旋转情况代码实现 删除操作查找操作 介绍 树表查找是一种在树形数据结构中…

非法捕捞识别预警系统 yolov7

非法捕捞识别预警系统通过yolov7网络模型AI视频分析技术&#xff0c;非法捕捞识别预警系统模型算法能够对河道湖泊画面场景中出现的非法捕捞行为进行7*24小时不间断智能检测识别实时告警通知相关人员及时处理。Yolo算法采用一个单独的CNN模型实现end-to-end的目标检测&#xff…

应用网关Nginx+Https证书+内网穿透+图片切割水印+网关登录

一、开源项目简介 Apiumc Gateway 它一个工具等于 Nginx Https证书 内网穿透 图片切割水印 网关登录 Apiumc Gateway 是高性能的Web网关&#xff0c;它从底层Socket原始通信层开始&#xff0c;采用多线程、多任务模式从新构建Web服务&#xff0c;充分发挥当下多核的CPU的…

当代年轻人搞副业有多野?工资6000,兼职1W...

凌晨12:00&#xff0c;我被同做新媒体的闺蜜小冉震了出来。 这是投稿出去&#xff0c;第10086次没有回声。 那种无力感掐着我的脖子&#xff0c;感觉整个人要窒息了。 写稿&#xff0c;真的好难&#xff0c;我好想放弃。 可是&#xff0c;每月被花呗、信用卡、房租支配的恐惧却…

C++【模板进阶】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C修行之路 &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 16.11.17 文章目录 &#x1f307;前言&#x1f3d9;️正文1、非类型模板参数1.1、使用方法1.2、类型要求1.3、实际例子&#xff1a;arr…

详解:三子棋以及N子棋的实现

三子棋以及N子棋的实现 初始化棋盘打印棋盘玩家下棋电脑下棋判断输赢主函数的实现(test.c)game.c的实现game.h的实现 铁汁们~今天给大家分享一篇三子棋以及N子棋的实现&#xff0c;来吧&#xff0c;开造⛳️ 实现流程&#xff1a; 1.游戏不退出&#xff0c;继续玩下一把&#x…

ML之FE:基于波士顿房价数据集利用LightGBM算法进行模型预测然后通过3σ原则法(计算残差标准差)寻找测试集中的异常值/异常样本

ML之FE&#xff1a;基于波士顿房价数据集利用LightGBM算法进行模型预测然后通过3σ原则法(计算残差标准差)寻找测试集中的异常值/异常样本 目录 基于波士顿房价数据集利用LiR和LightGBM算法进行模型预测然后通过3σ原则法(计算残差标准差)寻找测试集中的异常值 # 1、定义数据…

软件架构复习笔记(张友生教材版本)

考纲(张友生版本软件架构 考试题型&#xff1a; 10*3单选 5*3简答题 5*3设计图&#xff08;含画图&#xff09; 10*2 论述题 10*2综合题 复习以课件为主&#xff0c;书为辅 第一章 (软件危机) &#xff1f; &#xff1f; 构造模型与实现 掌握软件结构体系核心模型 第二章 软件体…

K8s之Pod最小调度单元详解

文章目录 一、Pod概念1、Pod是什么&#xff1f;2、Pod网络共享实现方式3、Pod存储共享方式4、创建Pod整体流程 二、使用YAML文件定义Pod资源1、Pod资源清单YAML文件书写技巧1. YAML语法格式&#xff1a;2. 配置Linux tab缩进两个空格3. 使用kubectl explain帮助命令 2、创建Pod…

ChatGPT客服系统产品-利用chatgpt训练企业知识开发个性化客服系统

打造最前沿的AI智能客服系统&#xff0c;基于自有数据语料&#xff0c;充分运用ChatGPT的大模型自然语言生成能力&#xff0c;定制化客服系统为企业提供自主性的客服服务能力。 ChatGPT如何革新智能客服&#xff1f; 根据当前ChatGPT的使用情况&#xff0c;我们发现未来中短期内…

基于 DDR3 的串口传图帧缓存系统设计实现(fifo2mig_axi )

文章目录 前言一、接口转换模块设计二、fifo2mig_axi 模块二、接口转换模块仿真四、fifo2mig_axi_tb五、仿真展示 前言 结合串口接收模块和 tft 显示屏控制模块&#xff0c;设计一个基于 DDR3 的串口传图帧缓存系统。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面…

次世代烘焙 法线贴图 相关知识

一般将低模 高模的法线贴图实现大量细节模型画面的游戏称为次时代游戏。 次世代常用软件 低模&#xff1a;Maya、3Dmax、Topogun 。 中模&#xff1a;Maya、3Dmax 。 高模&#xff1a;Maya、3Dmax、Zbrush。 UV&#xff1a;Maya、Zbrush、Unfold3D、Uvlayout 。 烘焙&#x…

【观察】华为重构分销伙伴体系,坚持“长期主义”做大分销市场

毫无疑问&#xff0c;随着数字化转型的加速&#xff0c;当前不同类型、不同规模的企业&#xff0c;在面临数字化转型时呈现出了不同的困境和特征&#xff0c;同时对合作伙伴也提出了更高的要求&#xff0c;因此唯有通过“精耕细作”的方式才能更好地加速企业数字化转型的步伐。…

AdaSparse: 自适应稀疏网络的多场景CTR预估建模

▐ 摘要 CTR(Click-through rate)预估一直是推荐/广告领域重要技术之一。近年来&#xff0c;通过统一模型来服务多个场景的预估建模已被证明是一种有效的手段。当前多场景预估技术面临的挑战主要来自两方面&#xff1a;1&#xff09;跨场景泛化能力&#xff1a;尤其对稀疏场景&…

【分布式锁】Redisson分布式锁的使用(推荐使用)

文章目录 前言一、常见分布式锁方案对比二、分布式锁需满足四个条件三、什么是Redisson?官网和官方文档Redisson使用 四、Redisson 分布式重入锁用法Redisson 支持单点模式、主从模式、哨兵模式、集群模式自己先思考下,如果要手写一个分布式锁组件&#xff0c;怎么做&#xff…

深入理解Java虚拟机:JVM高级特性与最佳实践-总结-1

深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践-总结-1 Java内存区域与内存溢出异常运行时数据区域程序计数器Java虚拟机栈本地方法栈Java堆方法区 OutOfMemoryError异常Java堆溢出 垃圾收集器与内存分配策略对象是否可以被回收引用计数算法可达性分析算法 Java内存区域…

力库华为机试题练习

1、两数之和 arg [2, 3, 6, 5] target 4 for i in range(len(arg)): other target - arg[i] if other in arg[i1:]: print(i, arg[i1:].index(other)i1) else: print(“输入目标数在该列表中不存在”) 2、回文数 方法一&#xff1a; class Solution: def isPalindrome(sel…

抖音小程序怎么压缩图片?教你使用抖音图片压缩助手

图片压缩是将原始图像的数据量进行减少&#xff0c;从而使其文件大小更小&#xff0c;但尽量保持原有图像质量的一种技术。通过对图片进行压缩&#xff0c;可以降低图片在传输过程中所需的带宽和存储空间&#xff0c;提高网站或应用程序的加载速度和响应速度。 此外&#xff0…