java 容器

news2025/1/10 10:55:11

java 容器

数组

数组的扩容问题

ArrayList 的默认初始化容量为0,首次添加元素时,创建容量为(10 || 添加集合大小) ,以后每次扩容的话,为当前容量的1.5倍

public ArrayList() {
    /*
    初始化容量大小为0
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    */
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

 private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //容量取 10 或 minCapacity
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
    //扩容机制,向右移动1位 即1.5倍
        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);
    }



并发访问数组问题

当我们遍历的同时修改数组元素的时候我们会面临并发修改数组的问题,比如我们使用 iterator 迭代器进行数组的遍历,同时使用 arrayList.remove进行元素的删除,则会导致并发修改异常。

导致并发修改的问题相当于文件快照版本号的对比。

private class Itr implements Iterator<E> {
		//在创建迭代器的时候会记录快照的版本号
        int expectedModCount = modCount;

        Itr() {}
}
//每次在next 或者 remove 的时候会进行快照的检查如果快照版本已经被修改则会导致 并发修改异常
public E next() {
    //检查版本号是否匹配
    checkForComodification();
}
final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}


解决方案:

使用 iterator 提供的 remove 方法,或使用 for() 从尾部进行迭代并删除(避免头部操作的话导致的数组越界异常

HashMap

ConcurrentHashMap

CopyOnWriteArrayList

从两个方面入手分析,分别从 add 方法,代表 操作数组的所有写的方法,二是从iterator方法,代表所有读的方法

 public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            //我们这里看到每次进行写入的时候我们都会进行加锁操作并且创建一个新的数组替换原有的数组
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }
public Iterator<E> iterator() {
    //创建iterator 并将数组的引用传递给iterator ,由于没有加锁,现在我们知道,我们读取的数据,并不一定是实时可见的
    return new COWIterator<E>(getArray(), 0);
}

Queue

queue 的继承关系图

queue 接口提供的方法

Summary of Queue methods
Throws exceptionReturns special value
Insert Queue#add add(e) Queue#offer offer(e)
Remove Queue#remove remove() Queue#poll poll()
Examine 查看但不进行元素删除的操作 Queue#element element() Queue#peek peek()

Deque 接口提供的方法

Summary of Deque methods
First Element (Head) Last Element (Tail)
Throws exceptionSpecial valueThrows exceptionSpecial value
Insert Deque#addFirst addFirst(e) Deque#offerFirst offerFirst(e) Deque#addLast addLast(e) Deque#offerLast offerLast(e)
Remove Deque#removeFirst removeFirst() Deque#pollFirst pollFirst() Deque#removeLast removeLast() Deque#pollLast pollLast()
Examine Deque#getFirst getFirst() Deque#peekFirst peekFirst() Deque#getLast getLast() Deque#peekLast peekLast()

BlockingQueue接口提供的方法

Summary of BlockingQueue methods
Throws exceptionSpecial valueBlocksTimes out
Insert #add add(e) #offer offer(e) #put put(e) #offer(Object, long, TimeUnit) offer(e, time, unit)
Remove #remove remove() #poll poll() #take take() #poll(long, TimeUnit) poll(time, unit)
Examine #element element() #peek peek()not applicablenot applicable

其他综合说明

ConcurrentLinkedQueue 是无限容量,LinkedBlockingQueue可以指定容量,在不指定容量时,默认容量为Integer 的最大值, ArrayBlockingQueue 需要指定容量,SynchronousQueue 容量为1,进行同步交换。

关于线程池还有一点说明,线程池中将command 从 blockingQueue 中取出时,并非用的 put 方法,而是使用的offer() 非阻塞方法。

//固定大小线程池使用的是  容量为interger 的最大值的  queue
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      threadFactory);
}
//单线程池使用的是  容量为interger 的最大值的  queue
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}
// 缓存线程池使用的是 同步的队列
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
}
//使用的是DelayedWorkQueue
public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

学习资料推广

我已经将springamqp 源码解析录制为视频上传到bibi,分为六个章节详细介绍了各个模块的具体内容

https://www.bilibili.com/video/BV1hN411Z7fn?share_source=copy_web

感兴趣的小伙伴可以看看
学习一下
录制不易,记得三联哦!

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

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

相关文章

CEAC之《计算机应用助理工程师》2

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;微微的猪食小窝 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 微微的猪食小窝 原创 收录于专栏 【CEAC证书】 1组合框的常用属性有 ____________ 。 A、Index B、Text C、Caption D、ListCountA,B,D2在…

ES6 入门教程 16 Reflect 16.2 静态方法 16.3 实例:使用 Proxy 实现观察者模式

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程16 Reflect16.2 静态方法16.2.1 Reflect.get(target, name, receiver)16.2.2 Reflect.set(target, name, value, receiver)1…

数据结构之:数组

数组初体验之数组中重复的数字 数组 &#xff1a; 有限个 相同类型的变量 组成的有序集合 int[] arr; int arr[]; // 静态初始化 String[] strArr {"和平精英","王者荣耀","开心消消乐","欢乐斗地主"}; // 动态初始化 String[] strAr…

自学 TypeScript 第三天 使用webpack打包 TS 代码

安装&#xff1a; 首先第一步&#xff0c;我们要初始化我们项目&#xff0c;在目录下输入 npm init 接下来&#xff0c;我们的安装几个工具 npm i -D webpack webpack-cli typescript ts-loader -D 意思是 开发依赖&#xff0c;也就是我们现在所安装的依赖都是开发依赖&am…

知乎 日报

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言评论界面首页cell的小标题的文字显示下拉刷新前言 这周完成了评论内容&#xff0c;改了一些小bug。收藏界面正在加油&#xff0c;FMDB库目前不是很理解 评论界面…

【C++初阶】三、类和对象(中)

在上一篇类和对象中&#xff0c;我们初步了解了类和对象的基本概念&#xff0c;知道了什么是类&#xff0c;接下来一起看看类和对象的具体细节和实现吧。&#xff08;以日期类举例&#xff09; 文章目录类和对象【中】1.类的6个默认成员函数2. 构造函数2.1 构造函数定义2.2 构造…

SpringBoot SpringBoot 开发实用篇 4 数据层解决方案 4.16 SpringBoot 整合 ES 客户端操作

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇4 数据层解决方案4.16 SpringBoot 整合 ES 客户端操作4.16.1 环境准备…

[附源码]java毕业设计停车场收费管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

DP入门(一)

前言&#xff1a;由于作者经常卡力扣周赛最后一题的dp&#xff0c;因此决定痛改前非&#xff0c;从头做人&#xff0c;争取下次能做出最后一道dp ak周赛&#xff01;呜呜呜加油~~ 因此 这个系列的文章不会教 dp &#xff0c;只会讲刷题思路&#xff0c;目前的计划是先更 lc 的题…

[Spring Cloud] RestTemplate跨进程调用

✨✨个人主页:沫洺的主页 &#x1f4da;&#x1f4da;系列专栏: &#x1f4d6; JavaWeb专栏&#x1f4d6; JavaSE专栏 &#x1f4d6; Java基础专栏&#x1f4d6;vue3专栏 &#x1f4d6;MyBatis专栏&#x1f4d6;Spring专栏&#x1f4d6;SpringMVC专栏&#x1f4d6;SpringBoot专…

【k8s】5、资源管理命令-声明式

文章目录一、 yaml和json介绍1、yuml语言介绍2、k8s支持的文件格式3、yaml和json的主要区别二、声明式对象管理1、命令式对象配置2、声明式对象配置3、声明式对象管理命令介绍三、编写资源配置清单1、 编写yaml文件2、 启动并查看资源3、创建service服务对外提供访问测试4、创建…

MySQL介绍

MySQL数据库最初是由瑞典MySQL AB公司开发&#xff0c;2008年1月16号被Sun公司收购。2009年&#xff0c;SUN又被Oracle收购。MySQL是目前IT行业最流行的开放源代码的数据库管理系统&#xff0c;同时它也是一个支持多线程高并发多用户的关系型数据库管理系统。MySQL之所以受到业…

基于51单片机的舞蹈机器人四路步进电机控制仿真

资料编号&#xff1a;091 下面是相关功能视频演示&#xff1a; 91-基于51单片机的舞蹈机器人四路步进电机控制仿真&#xff08;源码仿真全套资料&#xff09;功能介绍&#xff1a;通过51单片机控制4个步进电机旋转&#xff0c;模拟出机器人的四肢动作&#xff0c;全套资料齐全…

ES6 入门教程 17 Promise 对象 17.2 基本用法

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程17 Promise 对象17.2 基本用法17 Promise 对象 17.2 基本用法 ES6 规定&#xff0c;Promise对象是一个构造函数&#xff0…

【Java高级】一篇文章带你搞懂线程

目录 | 线程概述 | 线程创建 方式一&#xff1a;继承 Thread 类 方式二&#xff1a;实现 Runnable 接口 一些小细节 方式三&#xff1a;实现 Callable 接口&#xff08;JDK1.8&#xff09; | 线程生命周期 生命周期概述 [获取线程信息] 方法 set/getName current [运…

ArcGIS绘制北半球俯视投影地图

做全球碳水循环,植被变化,极端气候相关研究的同学都知道。北半球是核心,因为北半球的核心区域(东亚湿润区,中亚干旱半干旱,青藏高原,阿拉伯半岛,非洲北部沙漠以及美国西部等等核心区): 对于北半球的展示一般采用下面的图: 那么该如何做呢? 熟悉地图学的同学都知道…

Dubbo-聊聊Dubbo协议

前言 Dubbo源码阅读分享系列文章&#xff0c;欢迎大家关注点赞 SPI实现部分 Dubbo-SPI机制 Dubbo-Adaptive实现原理 Dubbo-Activate实现原理 Dubbo SPI-Wrapper 注册中心 Dubbo-聊聊注册中心的设计 Dubbo-时间轮设计 通信 Dubbo-聊聊通信模块设计 什么是协议 在网络交…

【FreeRTOS】FreeRTOS删除任务vTaskDelete()

使用说明&#xff1a; 任务中。小时 &#xff08;任务句柄_t xTask&#xff09;; INCLUDE_vTaskDelete必须定义为1&#xff0c;才能使用此函数。有关更多信息&#xff0c;请参见RTOS配置文档。 从RTOS内核管理中删除任务。正在删除的任务将从所有就绪、阻止、暂停和事件列表中删…

CEAC 之《计算机应用助理工程师》1

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;微微的猪食小窝 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 微微的猪食小窝 原创 收录于专栏 【CEAC证书】 1组合框有3种不同的类型&#xff0c;这3种类型是下拉式组合框、简单组合框、下拉式列表框&…

12. PyQt5实现多页面切换之QTabBar

PyQt5 QTabBar 类 QTabBar 类直接继承自 QWidget。该类提供了一个选项卡栏&#xff0c;该类仅提供了一个选项卡&#xff0c; 并没有为每个选项卡提供相应的页面&#xff0c;因此要使选项卡栏实际可用&#xff0c;需要自行为每个选项 卡设置需要显示的页面&#xff0c;可以通过 …