您的位置:首页 > 编程语言 > Java开发

java中ArrayList与LinkedList的比较

2015-03-13 17:00 357 查看
先来比较一下两者add(Object obj)的源码实现区别:

ArrayList:

当new一个ArrayList的时候,会调用其构造方法创建一个Object elementData[],用来存放数据,而EMPTY_ELEMENTDATA则是:final Object EMPTY_ELEMENTDATA[] = new Object[0];

public ArrayList()
{
elementData = EMPTY_ELEMENTDATA;
}

添加一个数据时,先调用ensureCapacityInternal(int i)方法对当前数组进行扩容,详细代码如下:

private void ensureCapacityInternal(int i)
{
if(elementData == EMPTY_ELEMENTDATA)
i = Math.max(10, i);
ensureExplicitCapacity(i);
}

private void ensureExplicitCapacity(int i)
{
modCount++;
if(i - elementData.length > 0)
grow(i);
}

private void grow(int i)
{
int j = elementData.length;
int k = j + (j >> 1);
if(k - i < 0)
k = i;
if(k - 2147483639 > 0)
k = hugeCapacity(i);
elementData = Arrays.copyOf(elementData, k);
}


添加当前对象

public boolean add(Object obj)
{
ensureCapacityInternal(size + 1);//添加数据前先进行扩容
elementData[size++] = obj;//把当前需要添加的对象放在数组的的最后一个位置
eturn true;
}


LinkedList:

当new一个LinkedList时,调用构造方法进行初始化,把size设为0;

public LinkedList()
{
size = 0;
}


添加数据

public boolean add(Object obj)
{
linkLast(obj);
return true;
}
//linkLast方法为把传入该方法的Object对象放在链表的最后一个位置
void linkLast(Object obj)
{
Node node1 = last;
Node node2 = new Node(node1, obj, null);//调用Node的构造方法,把obj变成Node对象
last = node2;
if(node1 == null)
first = node2;
else
node1.next = node2;
size++;
modCount++;
}

private static class Node
{

Object item;
Node next;
Node prev;

Node(Node node1, Object obj, Node node2)
{
item = obj;
next = node2;
prev = node1;
}
}


再来比较一下两者remove(int i)的源码实现区别:

ArrayList:

public Object remove(int i) {
rangeCheck(i);              // 判断数组有没有下标越界
modCount++;
Object obj = elementData(i); // 取出下标为i的元素
int j = size - i - 1;
if (j > 0)                  // 如果j>0说明第i个元素不是该数组的最后一个元素
System.arraycopy(((Object) (elementData)), i + 1,
((Object) (elementData)), i, j);// 实现数组的复制
elementData[--size] = null;   //如果j不大于0,说明j是最后一个元素了,则把最后一个元素直接指向空,并且自减1
return obj;
}

Object elementData(int i) {
return elementData[i];// elementData是Object数组
}

private void rangeCheck(int i) {
if (i >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(i));
else
return;
}


另外解释一下System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

src:源数组; srcPos:源数组要复制的起始位置; dest:目的数组; destPos:目的数组放置的起始位置; length:复制的长度。

举例说明:假如有一个ArrayList array,里面的元素为{2,5,7,4,9,6,10},size=7,如果要删除7,也就是删除index=2的数据;

src = array;dest = array;

System.arraycopy(src, 2+1,dest, 2, 4);

在src中,从index=2的下一位(也就是index=3)开始copy 4个数({4,9,6,10}),放到dest中,从index=2(也就是被删除的数据的位置)开始,结果为{2,5,4,9,6,10}

这样就完成了remove操作。

LinkedList:

LinkedList里的元素存放在Node里,Node里有三个field,分别是Object item、Node next、Node prev,它们分别是当前节点对象、当前节点的下一个对象、当前节点的前一个对象。

private static class Node
{

Object item;
Node next;
Node prev;

Node(Node node1, Object obj, Node node2)
{
item = obj;
next = node2;
prev = node1;
}
}

public Object remove(int i)
{
checkElementIndex(i);//判断有没有数组下标越界
return unlink(node(i));
}

Object unlink(Node node1)
{
Object obj = node1.item;//取出当前节点对象
Node node2 = node1.next;//取出当前节点对象的下一个对象
Node node3 = node1.prev;//取出当前节点对象的上一个对象
if(node3 == null) //如果node3==null为true,说明当前节点对象为first.
{
first = node2;
} else
{
node3.next = node2;
node1.prev = null;
}
if(node2 == null) //如果node2==null为true,说明当前节点对象为last.
{
last = node3;
} else
{
node2.prev = node3;
node1.next = null;
}
node1.item = null; //把当前节点对象指向空
size--;
modCount++;
return obj;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  List
相关文章推荐