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];
添加一个数据时,先调用ensureCapacityInternal(int i)方法对当前数组进行扩容,详细代码如下:
添加当前对象
LinkedList:
当new一个LinkedList时,调用构造方法进行初始化,把size设为0;
添加数据
再来比较一下两者remove(int i)的源码实现区别:
ArrayList:
另外解释一下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,它们分别是当前节点对象、当前节点的下一个对象、当前节点的前一个对象。
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;
}
相关文章推荐
- [转载] Java ArrayList、LinkedList、Vector比较
- 面试Java基础之ArrayList、LinkedList、Vector比较
- Java(ArrayList和LinkedList)、(HashTable与HashMap)、(HashMap、Hashtable、LinkedHashMap和TreeMap比较)
- Java 容器 & 泛型:二、ArrayList 、LinkedList和Vector比较
- Java集合源码学习笔记(五)ArrayList,LinkedList,Vector和Hashtable,HashMap的比较
- Java中LinkedList与ArrayList遍历速度比较
- Java基础之ArrayList、LinkedList、Vector比较之代码示例
- Java中ArrayList和LinkedList的比较
- Java Collections Framework - Java集合框架之List篇 ArrayList与LinkedList等的性能比较
- Java Collections Framework - Java集合框架之List篇 ArrayList与LinkedList等的性能比较
- java性能优化-Arraylist与Linkedlist整改查性能比较
- Java记录 -50- ArrayList与LinkedList比较分析
- java非并发容器ArrayList 和 LinkedList 优缺点比较及其实现源码分析
- Java中arraylist和linkedlist源码分析与性能比较
- java(20130801)异常、集合、ArrayList和LinkedList的比较、Vector和ArrayList的异同
- Java Collections Framework - Java集合框架之List篇 ArrayList与LinkedList等的性能比较
- Java 容器 & 泛型(2):ArrayList 、LinkedList和Vector比较
- Java性能优化-Arraylist与Linkedlist整改查性能比较的简介与内容
- java-集合(4)-用LinkedList来实现栈/队列-ArrayList和LinkedList比较
- java的list几种实现方式的效率(ArrayList、LinkedList、Vector、Stack),以及 java时间戳的三种获取方式比较