ArrayList 的实现分析
来源:互联网 发布:电脑拍照软件 清晰 编辑:程序博客网 时间:2024/05/08 15:12
1. 实现原理:
内部结构是数组。
2. 特点:
查找快,改动慢。
3. 下面以增删改查为例,进行分析
3.1 增:
介绍: 先调用ensureCapacityInternal(size +1 ),确保ArryList 容器的容量可以存下当前的值,不溢出。一下为增加操作的函数代码、
size :当前存入的个数。把要存入的数据存到最后一位。
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true;}
private void ensureCapacityInternal(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity);}
增加的策略:
int newCapacity = oldCapacity + (oldCapacity >> 1);
oldCapacity 向右位移一位,相当于加上原来容量/2
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);}
带索引的增加(插入):
1. 先检查索引值是否在当前的 size (即当前存储的序列号中)
2. 确保容量
3. 增加,增加位的后一位到最后一位 存储的数据 依次向后移动一位
4. 插入到索引位置
5. size 增加
public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++;}
3.2 删除(移除):
分两种: 带索引的移除,对象的移除
索引移除:
1. 检查是否在size和0 之间,否则抛出IndexOutOfBoundsException
2. modCount++ ,用于迭代故障,只知道这些了
3. 取出要移除的元素,用于返回值
4. 计算要移动的数据个数
5. 开始移动
6. 最后一位置空
public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work return oldValue; }
对象移除
- 因为ArrayList 中是可以存储null 元素的, 先判断是否为空,因为可能出现下面情况
String s1 = null;
String s2 = null;
s1.equals(s2) , 直接报空指针异常了 - 循环遍历,移除指定元素。
public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; }
移除元素方法,使用的是 系统提供的数组复制方法,需要注意的是将 最后一位置空
private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work}
3.3 改/查
比较简单,不做介绍
public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }public E get(int index) { rangeCheck(index); return elementData(index); }
4. java 中复制方法的总结:
- 使用FOR循环,将数组的每个元素复制或者复制指定元素,不过效率差一点
- 使用clone方法,得到数组的值,而不是引用,不能复制指定元素,灵活性差一点
- 使用System.arraycopy(src, srcPos, dest, destPos, length)方法,推荐使用
具体代码演示:
For 循环
int[] src={1,3,5,6,7,8};int[] dest = new int[6];for(int i=0;i<6;i++) dest[i] = src[i];
2.使用clone
int[] src={1,3,5,6,7,8};int[] dest;dest=(int[]) src.clone();//使用clone创建副本,注意clone要使用强制转换
3.使用System.arraycopy
int[] src={1,3,5,6,7,8};int[] dest = new int[6];System.arraycopy(src, 0, dest, 0, 6);
System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制.
其函数原型是:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
src:源数组; srcPos:源数组要复制的起始位置;
dest:目的数组; destPos:目的数组放置的起始位置;
length:复制的长度.
注意:src and dest都必须是同类型或者可以进行转换类型的数组.
有趣的是这个函数可以实现自己到自己复制,
比如:int[] fun ={0,1,2,3,4,5,6};
System.arraycopy(fun,0,fun,3,3);
则结果为:{0,1,2,0,1,2,6};
- ArrayList 的实现分析
- ArrayList的实现原理分析
- JDK中ArrayList的实现分析
- ArrayList的用法分析
- ArrayList的源码分析
- ArrayList源代码的分析
- ArrayList 的源码分析
- 深入分析ArrayList实现原理
- java学习之旅59--模拟ArrayList容器的底层实现_JDK源码分析ArrayList
- 59_数组_模拟ArrayList容器的底层实现_JDK源码分析ArrayList
- ArrayList类的实现
- ArrayList的实现原理
- ArrayList的实现
- ArrayList的实现原理
- ArrayList的实现原理
- ArrayList的实现
- ArrayList的实现原理
- ArrayList的实现原理
- Advanced Programming in UNIX Environment Episode 14
- 6.3
- HDFS文件
- 摧毁数组
- 摩尔定律对IT未来发展的影响
- ArrayList 的实现分析
- 那些年在Opencv遇到过的Mat坑
- CSS中上下左右提示框主要代码
- linux中的系统恢复
- JDBC学习笔记(1)—JDBC概述
- Effective C++ 49. Understand the behavior of the new-handler
- 机器学习(3)-逻辑回归
- 数学之美,判断两个线段相交
- Linux系统学习之系统启动的5个过程