ArrayList源码分析
来源:互联网 发布:suse yum配置 编辑:程序博客网 时间:2024/05/01 05:19
常用集合类
1. ArrayList 源码分析
ArrayList内部使用的是一个数组来保存数据. 主要是利用
Arrays.copyOf()
方法来动态扩展数组长度. ArrayList还是相对简单的.
1.1 ArrayList原理
ArrayList内部使用了一个 Object[]
来存储数据。
// 存储数据的数组private transient Object[] elementData;
ArrayList初始化时可以指定数组大小
// 指定数组大小,初始化ArrayList.public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity];}
如果不指定大小则, 默认是空数组
// 默认空数组定义private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};// 无参数构造方法public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
1.2 ArrayList 优化函数.
当不在添加元素时, 将剩余的空间释放掉.
public void trimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); }}
1.3 增加元素API
默认情况下元素添加到最后一个元素的后面
public boolean add(E e) { // 设置数组长度, 确保数组够长.如果不够会自动增加长度. ensureCapacityInternal(size + 1); // Increments modCount!! // size是当前元素个数. 下面这句代码是将元素添加到最后. elementData[size++] = e; return true;}
下面来看下 ensureCapacityInternal
更新数组实际长度的方法.
private void ensureCapacityInternal(int minCapacity) { modCount++; // 判断当前数组长度是否小于数组长度. 如果不小于则增加长度. if (minCapacity - elementData.length > 0) grow(minCapacity);}
下面来看下 grow
方法源码.
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);}
上面的代码非常简单首先将数组长度增加2倍, 如果还是不够长度, 则直接将长度增加到minCapacity.之后还要比较此时长度是否超过最大长度.处理过程如下
private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;}
在指定位置添加元素API
public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! // 将要插入位置以后的元素, 整体后移. System.arraycopy(elementData, index, elementData, index + 1, size - index); // 在index位置插入. elementData[index] = element; size++;}
1.4 删除元素API
remove(index)
public E remove(int index) { rangeCheck(index); modCount++; // 获取要删除元素值. E oldValue = elementData(index); // 获取要删除元素的个数. int numMoved = size - index - 1; // 将index 之后的元素前移 if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); // 将最后一个位置设置为null elementData[--size] = null; // clear to let GC do its work return oldValue;}
ArrayList的结构相对简单.也容易理解.
阅读全文
0 0
- ArrayList源码分析
- ArrayList源码分析
- ArrayList 源码分析
- ArrayList源码分析
- ArrayList LinkedList 源码分析
- ArrayList,LinkedList源码分析
- 源码分析之ArrayList
- ArrayList 源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList 源码分析
- Java ArrayList源码分析
- ArrayList源码分析
- Java ArrayList 源码分析
- ArrayList的源码分析
- haproxy+nginx+tomcat+memcache实现动静分离、会话同步集群
- 面试题64. 数据流中的中位数
- JavaScript中8个常见的陷阱
- Redis Sentinel安装部署与常用操作
- 验证码的实现VerifyCodeUtils
- ArrayList源码分析
- easyui datagrid 控件全选
- 自定义带shape的TextView
- PAT (Basic Level) Practise (中文)
- Replica Set配置一个隐藏的副本集成员
- 用nrm查看和切换当前使用的registry
- unicode转UTF8
- Phonegap 开发环境搭建
- vue.js导入高德地图