一、LinkedList类概述
(1)LinkedList类底层是基于双向链表结构实现的,不同于ArrayList类和Vector类是基于数组实现的;
(2)LinkedList类是非线程安全的;
(3)LinkedList类元素允许为null,允许重复元素;
(4)LinkedList类插入、删除效率高,查询效率低;
(5)LinkedList类基于链表实现的,因此不存在容量不足的问题,不用动态扩容;
(6)双向链表有三个区域,前指针域、数据域、后指针域。
(7)LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
(8)LinkedList 实现 List 接口,能对它进行队列操作。
(9)LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
(10)LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
(11)LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
(12)LinkedList 是非同步的。
二、LinkedList类的方法
与ArrayList类相似,LinkedList类常见方法也有add()、get()、remove()、set()、size()等,用法也类似。
Object getFirst() 它返回链表的第一个元素。
Object getLast() 它返回链接列表的最后一个元素。
boolean contains(Object element)如果元素存在于列表中,则返回true。
void clear():删除列表中的所有元素。
三、LinkedList类的特点
(1)LinkedList的底层结构为双向链表,将零散的内存单元通过附加的引用关联起来体现出其顺序性,相比数组的连续空间存储,链表对内存的利用率更高;
(2)有序:插入元素的顺序和取出顺序一致;
(3)可重复:可以插入相同的元素(元素值也允许为null);
(4)插入、删除操作效率高,和ArrayList恰恰相反,按索引查找效率较低;
(5)线程不安全:没有线程锁,多个线程同步进行写操作的时候可能导致数据错误;
(6)使用场景:不会随机访问数据,更多的插入删除操作,更少的查询读取操作。
四、LinkedList类简化版原码
public class QizeLinkedList {private Node first;//链表中第一个节点private Node last;//链表中最后一个节点private int size;//链表当前节点数private static class Node{E item;//当前节点的值private Node prev;//当前节点的上一个节点private Node next;//当前节点的下一个节点/*** 构造方法* @param prev* @param item* @param next*/public Node(Node prev, E item, Node next){this.item = item;this.prev = prev;this.next = next;}}/*** 插入方法** @param e*/public void add(E e){Node l = last;//获取链表中最后一个节点//最后一个节点就是新创建节点的上一个节点,新创建节点的下一个节点为nullNode newNode = new Node<>(l,e,null);last = newNode;if(l == null){//如果在链表中没有最后一个节点,链表为空first = newNode;}else {l.next = newNode;}size++;}/*** 利用折半查找算法来实现查询的方法** @param index* @return*/private Node node(int index){if(index < size >> 1){//如果index小于size值的一半,则查询链表中间值的左边Node f = first;for(int i=0;if = f.next;}return f;}else{//如果index大于size值的一半,则查询链表中间值的右边Node l = last;for(int i=size-1; i>index; i--){l = l.prev;}return l;}}/*** 查询方法* @param index* @return*/public E get(int index){//下标如果越界,需要做报错处理return node(index).item;}public E remove(int index){return unlink(node(index));}private E unlink(Node node){//根据index查询需要删除的node节点//获取删除节点的上一个节点和下一个节点Node prev = node.prev;//删除节点的上一个节点Node next = node.next;//删除节点的下一个节点final E element = node.item;//删除节点的元素值if(prev == null){//如果删除节点的上一个节点是null,则删除的节点是头节点first = next;}else {//删除节点上一个节点.next节点=删除节点的下一个节点prev.next = next;node.prev = null;}if(next == null){//如果删除节点的下一个节点是null,则删除的节点是尾节点last = prev;}else {//如果删除的不是尾节点,删除的下一个节点.prev=删除的上一个节点next.prev = prev;node.next = null;//gc回收}node.item = null;size--;return element;}public static void main(String[] args) {QizeLinkedList qizeLinkedList = new QizeLinkedList();qizeLinkedList.add("qize1");qizeLinkedList.add("qize2");qizeLinkedList.add("qize3");System.out.println("--------------------");System.out.println(qizeLinkedList.get(0));System.out.println(qizeLinkedList.get(1));System.out.println(qizeLinkedList.get(2));System.out.println("--------------------");qizeLinkedList.remove(1);System.out.println(qizeLinkedList.get(1));System.out.println("--------------------");}
}