什么是LinkeList
LinkedList和ArrayList一样是集合List的实现类,其数据结构是链表,每个结点用内部类Node表示,有item、prevent、next三个属性,另外first、last是第一和最后一个元素
链表数据结构的特点:
每个元素分配的空间不必连续
插入和删除元素时速度非常快[直接修改指针]
访问元素的速度较慢[需要遍历]
代码demo
public class MyLinkedList {
public static void main(String[] args){
LinkedList<Integer> list = new LinkedList<Integer>();
//在链尾添加一个元素,返回成功失败
boolean suc = list.add(1);
//在链表头部添加一个元素
list.addFirst(0);
list.add(1, 2);
list.add(2, 3);
list.add(2, 4);//此时链表为[0,2,4,3,1]
//移除指定位置的元素,参数为int,返回对应的元素
list.remove(1);
//移除指定元素,参数为Object,这也是泛型基本类型,而需要包装类型的原因?返回为boolean
list.remove(new Integer(1));
//removeFirst(与list.remove()作用相同)和removeLast方法
//存储结构是链表,需要遍历(从头或者尾),取到node,返回node的item值
//ArrayList的存储结构是数组,直接取下标
Object nodeItem = list.get(1);
//同样有getFirst和getLast方法
for(Integer i : list){
System.out.print(i);
}
//一般不要用for循环
for (int i=0;i<list.size();i++) {
System.out.print(list.get(i));
}
Iterator<Integer> i = list.iterator();
while(i.hasNext()){
//注意:循环删除的时候使用迭代器,一定要有i.next()
System.out.print(i.next());
}
}
}
一些问题
为什么ArrayList的插入和删除比LinkedList要慢?
ArratList的插入删除,需要将后面所有的元素往后往前移一位,也就是每个元素都要copy一遍
LinkedList是双向链表,将前节点的next和后节点的previous指向自己,虽然查找要插入的位置要比ArrayList查找的慢(为什么LinkedList的修改要比ArrayList慢?),但是后面的过程快,磨刀不误砍柴工
为什么LinkedList的查找和修改要比ArrayList慢?
ArrayList的内部存储结构是数组,可以通过下标迅速定位到元素
LinkedList的内部存储结构是链表,是没有下标的,只能通过nodex(index)方法去查找,其代码逻辑为,从firs或node开始遍历
用哪种遍历方式最快?为什么?
遍历包含10万个元素的LinkedList,foreach语句效率最高,其次是迭代器,效率最差的是for循环
遍历LinkedList时,使用顺序访问比较快,Iterator的next()方法就是顺序,foreach循环(内部使用的是iterator)和迭代器都是顺序访问
遍历ArrayList时,使用随机访问(通过索引序号访问)效率最高,for循环的get()就是随机访问,而使用迭代器的效率最低!
fail-fast机制是什么
或者问:不要在foreach循环中使用remove/add操作,要使用Iterator.remove?
原因:底层代码中,集合在遍历的时候,维护了一个游标,代码先判断是否hasNext,然后再去调用next;当游标=size的时候,hasNext判断false,退出循环
当操作【如游标2,size为3,删除2,不等=>再次循环,游标3,size为2,不等=>再次循环,报错】
除非删除完break,跳出循环,不再执行next方法
ModCoun代表集合被修改的次数,ArrayList、LinkedList、HashMap有一个判断modCount != expectedModCount