首先和数组同样,LinkedList也是一种线性数据结构,用链表实现的集合,元素有序且能够重复能够为nulljava
因为其容许内存进行动态分配,意味着内存分配是由编译器在运行时完成的,咱们无需在LinkedList声明的时候指定大小node
其也不须要在连续的位置上存储元素,由于节点能够经过引用指定下一个节点或者前一个节点,致使插入和删除的成本很低。git
LinkedList的实现是基于双向链表的,且头结点中不存放数据github
和 ArrayList 同样,不是同步容器web
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SAFdrM8w-1597210837179)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200811170511.png)]数组
也实现了Cloneable接口和Serializable接口,分别用来支持克隆以及序列化。数据结构
其是一个继承自AbstractSequentiaList的双向链表,所以它也能够被当作堆栈、队列或双堆队列进行操做svg
因为其实现了List接口,因此能对它进行队列操做函数
因为实现了Deque接口,因此能将LinkedList当作双端队列使用this
LinkedList中的每个元素均可以称之为节点,每个节点都包含三个项目,其一就是元素自己,其二是执行像一个元素的引用地址,其三是指向上一个元素的引用地址
Node是LinkedList类的一个私有的静态内部类
private static class Node<E> { E item;// 实际存储元素 Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
LinkedList有两个构造函数,一个是默认的空的构造函数,一个是将已有元素的集合Collection的实例添加到LinkedList中,调用的是addAll方法。
LinkedList有不少add方法,可是每次添加元素只是改变对应节点的上下指针引用,并且没有扩容,因此效率仍是很不错的
将指定元素添加到链表头
public void addFirst(E e) { linkFirst(e); } private void linkFirst(E e) { final Node<E> f = first;// 将头节点赋值给f final Node<E> newNode = new Node<>(null, e, f);//将指定元素构形成一个新节点,此节点的指向下一个节点的引用为头节点 first = newNode; if (f == null) last = newNode; else f.prev = newNode; size++; modCount++; }
和插入头节点差很少,逻辑层面基本同样
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++; }
将指定的元素插入此列表中的指定位置
按照指定集合的迭代器返回的顺序,将指定集合中的全部元素追加到此列表的末尾
删除元素和添加元素基本一致,就是改变对应元素指向上一节点和下一节点的引用便可。
从列表中移除第一个元素并返回该元素
从列表中删除最后一个元素并返回该元素
删除此列表中指定位置的元素
若是存在,则从该列表中删除指定元素的第一次出现
用指定的元素替换此列表中指定位置的元素,主要是经过node(index)方法获取指定索引位置的几点,而后修改此节点位置的元素
返回此列表中第一个元素
返回此列表中的最后一个元素
返回指定索引处的元素
返回此列表中指定元素第一次出现的索引,若是此列表中不包含元素,则返回-1
须要注意的是,modCount 字段,前面咱们在增长和删除元素的时候,都会进行自增操做 modCount,这是由于若是想一边迭代,一边用集合自带的方法进行删除或者新增操做,都会抛出异常。(使用迭代器的增删方法不会抛异常)
主要利用get(int index)方法
Iterator<String> listIt = linkedList.listIterator(); 9 while(listIt.hasNext()){ 10 System.out.print(listIt.next()+" "); 11 } 12 13 //经过适配器模式实现的接口,做用是倒叙打印链表 14 Iterator<String> it = linkedList.descendingIterator(); 15 while(it.hasNext()){ 16 System.out.print(it.next()+" "); 17 }
在其集合中也有一个内部类Listltr,
其底层使用的也是迭代器本质同样
迭代器和for循环效率差别
普通for循环:每遍历一个索引的元素以前,都要访问以前的全部索引
16 System.out.print(it.next()+" ");
17 }
在其集合中也有一个内部类Listltr, ##### foreach循环 其底层使用的也是迭代器本质同样 > 迭代器和for循环效率差别 > > 普通for循环:每遍历一个索引的元素以前,都要访问以前的全部索引 > > 迭代器:每次访问一个元素之后,都会用游标记录当前访问元素的位置,遍历一个元素,记录一个元素