数据结构之顺序存储结构(ArrayList源码分析)
2017-10-09 09:47
471 查看
数据结构是数据在计算机内存或磁盘中的组织形式。按照逻辑结构来划分,可分为集合结构、线性结构、树形结构、图形结构;按照存储结构来划分可分为顺序存储结构和链式存储结构。以下简单介绍顺序存储结构:
顺序存储结构是每个元素挨着下一个元素,存储位置连续,这种数据结构的好处就是方便获得各个元素的内存地址。在java中,使用这种数据结构的类有ArrayList,以下对ArrayList源码进行分析。
打开ArrayList类,其构造方法:
public ArrayList() {
this(10);
}
当你new ArrayList()时,会调用无参构造方法,在无参构造方法中又指向有参构造方法,在有参构造方法中,指定创建长度为10的Object数组,其实数组就是顺序存储结构。分析ArrayList,无非就是其增删改查。先看看它如何添加一个数据:
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
System.arraycopy(elementData, index+1, elementData, index,numMoved);这句代码的意思就是把原数组删掉你要删除的元素,然后这个删除的元素后面的元素全部往前移动一位,构成新的数组重新赋给elementData;这就是ArrayList删除一个元素的过程。
接下来,看一下ArrayList获取数据的方法:
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
} 这个比较简单,同样先判断你传入的index是否会脚标越界,不会的话直接返回数组里面index对应的值。
接着看,ArrayList修改的数据的方法:
public E set(int index, E element) {
RangeCheck(index);
E oldValue = (E) elementData[index];
elementData[index] = element;
return oldValue;
}
根据index来修改对应的值,把新的值直接赋给elementData[index],达到修改的目的。
当然,ArrayList还有很多方法,在这里就不细细分析了。在看ArrayList源码后,总结如下,顺序存储结构在增删方面对资源开销比较大,因为你每增删一个元素,后面的元素必须都向前移动,但在查询方面还是比较快的,因为我们可以根据下标值去获取对应的值,这也是这种数据结构的优点,好了,本文到此,作为学习记录!
顺序存储结构是每个元素挨着下一个元素,存储位置连续,这种数据结构的好处就是方便获得各个元素的内存地址。在java中,使用这种数据结构的类有ArrayList,以下对ArrayList源码进行分析。
打开ArrayList类,其构造方法:
public ArrayList() {
this(10);
}
public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity); this.elementData = new Object[initialCapacity]; }
当你new ArrayList()时,会调用无参构造方法,在无参构造方法中又指向有参构造方法,在有参构造方法中,指定创建长度为10的Object数组,其实数组就是顺序存储结构。分析ArrayList,无非就是其增删改查。先看看它如何添加一个数据:
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } }其中size表示数组的长度,也就是ArrayList的长度,每add一次,size就加1,再看ensureCapacity()方法,首先是对原始数组长度和现在增加一个后的长度做对比,如果现在的长度已经大于原始的长度了,就必须对原来数组进行扩容,int newCapacity = (oldCapacity * 3)/2 + 1;然后把原始数组复制到新长度的数组里面,elementData = Arrays.copyOf(elementData, newCapacity);这个就是添加一个数据的过程。好,接下来看一下删除一个数据的过程:
public E remove(int index) { RangeCheck(index); modCount++; E oldValue = (E) 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; }首先,是根据下标值index来删除,先用RangeCheck()这个方法判断你传入的index是否越过你数组的长度,如果越过了就会报IndexOutOfBoundsException异常,没有的话就进行删除操作;int numMoved = size - index - 1;其中numMoved是表示删除某个元素后,需要向前移动元素的个数;如果numMoved大于0,说明你删除的不是最后一个元素,需要移动你删除那个元素后面的其他元素;
System.arraycopy(elementData, index+1, elementData, index,numMoved);这句代码的意思就是把原数组删掉你要删除的元素,然后这个删除的元素后面的元素全部往前移动一位,构成新的数组重新赋给elementData;这就是ArrayList删除一个元素的过程。
接下来,看一下ArrayList获取数据的方法:
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
} 这个比较简单,同样先判断你传入的index是否会脚标越界,不会的话直接返回数组里面index对应的值。
接着看,ArrayList修改的数据的方法:
public E set(int index, E element) {
RangeCheck(index);
E oldValue = (E) elementData[index];
elementData[index] = element;
return oldValue;
}
根据index来修改对应的值,把新的值直接赋给elementData[index],达到修改的目的。
当然,ArrayList还有很多方法,在这里就不细细分析了。在看ArrayList源码后,总结如下,顺序存储结构在增删方面对资源开销比较大,因为你每增删一个元素,后面的元素必须都向前移动,但在查询方面还是比较快的,因为我们可以根据下标值去获取对应的值,这也是这种数据结构的优点,好了,本文到此,作为学习记录!
相关文章推荐
- 数据结构与算法学习(一)顺序存储结构ArrayList源码分析
- 【OpenVswitch源码分析之六】内核空间转发面数据结构与流程
- [Java数据结构]从源码分析HashMap
- HDFS源码分析心跳汇报之数据结构初始化
- linux内核源码分析(内存管理)--之数据结构
- 数据结构与算法学习(二)链式存储结构LinkedList源码分析
- HDFS源码分析心跳汇报之数据结构初始化
- nginx源码分析2———基础数据结构二(链表和双向链表)
- 数据结构之重写ArrayList的底层源码
- HDFS源码分析(三)-----数据块关系基本结构
- nginx源码分析2———基础数据结构三(内存池)
- 线性表数据结构解读(一)顺序存储结构ArrayList
- 数据结构与算法之LinkedList源码分析
- redis源码分析之数据结构(一)链表adlist.c
- 分析Java中ArrayList与LinkedList列表结构的源码
- MySQL系列:innodb源码分析之基础数据结构
- 用lex分析C源码中数据结构关系拓扑图
- [Java数据结构]从源码分析HashMap
- 基础数据结构之LinkedHashMap源码分析
- 基础数据结构之TreeMap源码分析