ArrayList
ArrayList内部使用的了一个Object数组来存储数据元素,所以ArrayList开辟的是一块连续的内存,是顺序存储的,有所有顺序存储的特性,查询快,插入删除慢。
注意点:不可以for循环的remove ArrayList的元素
值得一提的是,在for循环中是不可以直接remove元素的,否则很容易出现IndexOutOfBoundsException异常,为什么呢,
查看源码,可以知道,remove的过程其实是删除某个节点,然后将节点后的元素都向前移动了,但是for循环结束条件的ArrayList对象并没有同步更改,
因为这是在同一个线程中,还没来得及改,所以就会出现,10个元素的ArrayList已经remove掉三四个元素了,但是for循环的结束条件中的ArrayList对象依然是9,这就是为什么,在执行for循环remove过程中出现了IndexOutOfBoundsException异常的现象。
注意点2 那怎么安全的remove ArrayList的元素呢?
当然是使用迭代器,如果需要在for循环中做删除,需要使用ArrayList内部迭代器内部类提供的remove方法。
注意点:不可以for循环的remove ArrayList的元素
值得一提的是,在for循环中是不可以直接remove元素的,否则很容易出现IndexOutOfBoundsException异常,为什么呢,
查看源码,可以知道,remove的过程其实是删除某个节点,然后将节点后的元素都向前移动了,但是for循环结束条件的ArrayList对象并没有同步更改,
因为这是在同一个线程中,还没来得及改,所以就会出现,10个元素的ArrayList已经remove掉三四个元素了,但是for循环的结束条件中的ArrayList对象依然是9,这就是为什么,在执行for循环remove过程中出现了IndexOutOfBoundsException异常的现象。
注意点2 那怎么安全的remove ArrayList的元素呢?
当然是使用迭代器。
LinkedList
LinkedList是链式存储的,具有链式存储的所有特性,查询慢,插入删除快。
LinkedList是链表,而且是双向链表,但是不是循环双向链表。LinkedHashMap是双向循环列表的数据结构。
LinkedList怎么设计?内部只需要定义一个头结点,然后定义了一个private static final的内部类Node。Node就是节点,节点里面都包括什么东西?
包括3个内容:数据部分、指针部分、节点的指向关系。(节点的数据data部分、节点的前驱previous和后继next的引用、构造方法)。
有前驱也有后继,说明LinkedList使用的是双向链表。
因为LinkedList使用的是链表的存储结构,内存可以是连续的也可以是不连续的,所以只需要知道头结点,就可以依次找到其他节点。
头节点不存储数据。
LinkedList的toArray:
public Object[] toArray(){
int index=0;
Object[] contents = new Object[size];
// voidLink 是头结点,不保存数据只作为头节点
Link<E> link = voidLink.next;
while(link != voidLink){
contents[index++] = link.data;
link = link.next;
}
return contents;
}
set、remove的时候都会折半查找来提高效率,index大于size/2从后面往前查找,index小于size/2则从前面往后查找。
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
transient Node<E> first;
private static final class Node<ET> {
ET data;
Node<ET> previous,next;
Node(ET o, Node<ET> p, Node<ET> n){
data=o;
previous=p;
next=n;
}
}
}