java ArrayList 原理
概述
底层通过数组实现,所以 查询/更新效率很高,删除/增加跟位置相关,除未实现同步外和 Vector 大致相同
自动扩容,每次扩容大概 1.5 倍,扩容代价比较高尽量避免
实现了 RandomAccess 接口,使用 for 遍历效率高
最大长度为 Integer.MAX_VALUE
扩容
扩容是自动扩容的,每次扩容大概1.5倍
扩容是复制一个新的数组,并把新的数组的长度设置为原来的 1.5 倍,原来的数组就不用了。代价很高,需要尽量避免,可以初始化时指定长度或者添加大量元素前手动调用 public void ensureCapacity(int minCapacity) 来扩容一次,避免后续自动多次扩容
public boolean add(E e) {
// 数组扩容,不是一定要扩容,需要扩容才扩容
// 初始化 ArrayList 时如果不指定长度或者指定长度为0,size 就是 0(属性 size 是 int,默认值是0)
ensureCapacityInternal(size + 1);
// 数组最后一个位置存放新增的元素(elementData是底层存放数据的数组)
elementData[size++] = e;
return true;
}
// 扩容方法具体逻辑(minCapacity 是 size+1)
private void ensureCapacityInternal(int minCapacity) {
// calculateCapacity(elementData, minCapacity):确定数组添加元素后的真实长度
// ensureExplicitCapacity():1,记录 list 修改次数;2,添加元素后是否扩容
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
// 确定数组添加元素后真实长度逻辑
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// 初始化 ArrayList 没有指定长度或指定长度是0时 elementData 就等于 DEFAULTCAPACITY_EMPTY_ELEMENTDATA(构造方法)
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 如果初始化时没有指定长度或长度是0时,size 是 0,minCapacity = size+1,所以 minCapacity 就是1
// DEFAULT_CAPACITY 是 10,两者取其大作为 数组长度
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
// 如果初始化时指定了长度,那么就是 size+1 为数组长度
return minCapacity;
}
// 真正的扩容处理
private void ensureExplicitCapacity(int minCapacity) {
modCount++; // 记录修改次数
// 如果新的长度大于原来的长度就扩容
if (minCapacity - elementData.length > 0)
// 进入这里就表明需要扩容了(大约原来的长度1.5倍):1,复制一个新的数组;2,更新 size(然后回到 add() 方法中把元素放在数组末尾)
grow(minCapacity);
}
添加元素 add 和 addAll 方法
如果是尾部添加,并且添加元素后数组的长度不超过原来的长度,效率是比较高的;如果指定下标位置添加(不是尾部添加),会涉及元素的移动(当前下标之后的元素都向后移动,把当前位置设置为新元素)这时代价是比较高的
remove() 方法是 add() 的逆过程,如果指定下标,也会涉及元素移动,代价比较高
获取和修改 get 和 set
不会涉及元素移动,效率是很高的
java ArrayList 原理的更多相关文章
- Java集合 ArrayList原理及使用
ArrayList是集合的一种实现,实现了接口List,List接口继承了Collection接口.Collection是所有集合类的父类.ArrayList使用非常广泛,不论是数据库表查询,exce ...
- JAVA监听器原理
http://blog.csdn.net/longyulu/article/details/25054697 JAVA监听器原理 标签: 监听器 2014-05-05 15:40 9070人阅读 评论 ...
- Java编译原理
http://wenku.baidu.com/view/f9b1734b87c24028915fc3a3.html Java编译原理 1. 关于动态加载机制 学习Java比C++更容易理解OOP的思想 ...
- Java:HashMap原理与设计缘由
前言 Java中使用最多的数据结构基本就是ArrayList和HashMap,HashMap的原理也常常出现在各种面试题中,本文就HashMap的设计与设计缘由作出一一讲解,并解答面试常见的一些问题. ...
- [JavaEE]Java NIO原理图文分析及代码实现
转http://weixiaolu.iteye.com/blog/1479656 目录: 一.java NIO 和阻塞I/O的区别 1. 阻塞I/O通信模型 2. java NIO ...
- Java NIO原理分析
Java IO 在Client/Server模型中,Server往往需要同时处理大量来自Client的访问请求,因此Server端需采用支持高并发访问的架构.一种简单而又直接的解决方案是“one-th ...
- Java跨平台原理
此篇博文主要源自网络xiaozhen的天空的博客:http://xiaozhen1900.blog.163.com/blog/static/1741732572011325111945246/ 1.是 ...
- 【转】Java跨平台原理
原文地址:http://www.cnblogs.com/gw811/archive/2012/09/09/2677386.html 1.是么是平台 Java是可以跨平台的编程语言,那我们首先得知道什么 ...
- 《Java虚拟机原理图解》 1.2、class文件里的常量池
[最新更新:2014/11/11] 了解JVM虚拟机原理 是每个Java程序猿修炼的必经之路. 可是因为JVM虚拟机中有非常多的东西讲述的比較宽泛.在当前接触到的关于JVM虚拟机原理的教程或者博客中 ...
- Java NIO原理图文分析及代码实现
原文: http://weixiaolu.iteye.com/blog/1479656 目录: 一.java NIO 和阻塞I/O的区别 1. 阻塞I/O通信模型 2. java ...
随机推荐
- 实操记录之-----Ant Design of Vue 增强版动态合并单元格,自动根据数据进行合并,可自定义横纵向合并
前几天搞了个简易版的动态合并单元格 但是需求有变化,就只能稍微改改了~~ 欢迎路过的各位大佬指出我代码的问题~~~~ 另: 代码执行效率不是很高,如果需要大量渲染更多数据建议可以直接使用原生 < ...
- 【单片机】通过定时器实现模拟任意路PWM通道(带实例和计算方法)
前言说明 现在有很多单片机的硬件定时器都具备PWM输出功能,不过有时候会因为器件成本或硬件设计等原因,导致数量不够或者所使用的引脚不支持定时器输出.尴尬的是,笔者接手的项目两种情况都存在,项目需要支持 ...
- Android IO 框架 Okio 的实现原理,到底哪里 OK?
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 前言 大家好,我是小彭. 今天,我们来讨论一个 Square 开源的 I/O 框架 Okio,我们最开始接触 ...
- LeetCode 周赛 332,在套路里摸爬滚打~
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 大家好,今天是 3T 选手小彭. 上周是 LeetCode 第 332 场周赛,你参加了吗?算法解题思维需要 ...
- Backbone 网络-ResNet 论文解读
摘要 残差网络(ResNet)的提出是为了解决深度神经网络的"退化"(优化)问题. 有论文指出,神经网络越来越深的时候,反传回来的梯度之间的相关性会越来越差,最后接近白噪声.即更深 ...
- Python中的魔术方法大全
魔术方法 一种特殊的方法而已 特点 不需要人工调用,在特定时刻自动触发执行 魔术方法种类 1.__init__初始化方法******* 触发时机:实例化对象之后触发作用:为对象添加对象的所属成员参数: ...
- [IOI2013]robots 机器人
题目传送门 思路 简单题,设函数 \(f_i\) 表示当时间为 \(i\) 时是否能够收拾好所有玩具,则 \(f_i\) 显然是单调的. 所以我们可以考虑二分. 设我们当前二分到 \(x\),我们先把 ...
- Leaflet 调用腾讯瓦片地图服务demo
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" ...
- vue 组件通信方式 ,父子、隔代、兄弟 三类通信,六种方法
(1)props / $emit 适用 父子组件通信 (2) ref 与 $parent / $children 适用 父子组件通信 (3)$attrs / $listeners 适用于 隔代组件通信 ...
- BUG: kernel NULL pointer dereference, address: 0000000000000008
问题现象:有台实例是用于压测用的,只要是做TCP连接数压测时,连接数超过100多就会自动重启,各种日志里面看不到任何关于重启的报错 xxx云服务器供应商技术支持,后台工具检测到有panic迹象,但不确 ...