java中ArrayList与LinkedList的比较

先来比较一下两者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;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值