ArrayList和LinkedList学习
ArrayList和LinkedList学习
战地春梦 发表于1年前
ArrayList和LinkedList学习
  • 发表于 1年前
  • 阅读 12
  • 收藏 4
  • 点赞 0
  • 评论 0

腾讯云 学生专属云服务套餐 10元起购>>>   

#ArrayList和LinkedList学习 ##1.ArrayList

###1.1源码分析 //默认数组容量即长度为10 private static final int DEFAULT_CAPACITY = 10;

	//存储对象数组
	transient Object[] elementData; 
	
	//数组长度
	private int size;

	//最大数组长度
	private static final int MAX_ARRAY_SIZE = 	Integer.MAX_VALUE - 8;

	//为空的对象数组
	private static final Object[] 	DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

	//添加数据
	public boolean add(E e) {
	 	//检验数组长度
    	ensureCapacityInternal(size + 1);         			elementData[size++] = e;
    	return true;
	}
	
	private void ensureCapacityInternal(int minCapacity) 
	{
	//如果对象数组为空
    if (elementData == 	DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
    //容量为默认容量和当前数组容量的最大值
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    //确保当前容量是否需要扩容
    ensureExplicitCapacity(minCapacity);
    
    }
    
    
     private void ensureExplicitCapacity(int minCapacity) {
    //操作数加一
    modCount++;
   //如果当前数组容量大于存储对象数组大小
    if (minCapacity - elementData.length > 0)
    	//扩展容量
        grow(minCapacity);
}
 

//扩容 
private void grow(int minCapacity) {
    
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
    	//确认新的数组长度
        newCapacity = hugeCapacity(minCapacity);
    //进行拷贝操作
    elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) 
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

// 根据下标获取
public E get(int index) {
	//检验下标是否超过数组长度
    rangeCheck(index);
    return elementData(index);
}

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; 
    return oldValue;
}

##2.LinkedList

###2.1源码分析

	//链表长度
	transient int size = 0;
	
	//添加数据
	public boolean add(E e) {
    linkLast(e);
    return true;
	}
	
	//添加数据到链表尾部
    void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
   		//表示链表为空
        first = newNode;
    else
    	//链表不为空,则当前尾节点的下一节点为新节点
        l.next = newNode;
    //链表长度加一
    size++;
    //操作数加一
    modCount++;
    }
    
    //删除数据
    public E remove(int index) {
    //检验下标
    checkElementIndex(index);
    return unlink(node(index));
	}
    
    //根据下标获得节点
    Node<E> node(int index) {
	
	// >>:右移运算符,size >> 1,相当于size除以2的1次方
    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
	}
    
    
    
    //删除某个节点
    E unlink(Node<E> x) {
    
    // assert x != null;
    final E element = x.item;
    final Node<E> next = x.next;
    final Node<E> prev = x.prev;

    if (prev == null) {
        first = next;
    } else {
        prev.next = next;
        x.prev = null;
    }

    if (next == null) {
        last = prev;
    } else {
        next.prev = prev;
        x.next = null;
    }

    x.item = null;
    //链表长度减一
    size--;
    //操作数加一
    modCount++;
    
    return element;
	}

##3.比较

当读取数据时,采用ArrayList更快,因为是根据下标访问,时间为O(1),而

LinkedList会先遍历链表,才能找到下标代表的节点,时间为O(m)。

当写入,删除数据时,采用LinkedList更快,因为他通过修改头尾指针指向的对象,即可

完成添加,或者删除。而ArrayList则需要进行数组的拷贝。

共有 人打赏支持
粉丝 5
博文 33
码字总数 24598
×
战地春梦
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: