java集合之LinkedList

LinkedList结构图



1.List是一个接口,继承于collection接口,代表有序的队列
2.AbstractList是一个抽象类,继承于AbstractCollection。AbstractList实现了List接口中除了size(),get(int location)之外的方法
3.AbstractSequentialList是一个抽象类,它继承与AbstractSequentiaList实现了“链表中,根据index索引值操作操作链表的全部方法”
4.ArrayList、LinkedList、Vector和Stack是List的四个实现类,其中Vector是基于JDK1.0,虽然实现同步,但是效率低,已经不用,stack继承Vector
5.LinkedList是双向链表,同样可以被当作栈、队列或双端队列来使用
6.实现Serializable接口,LinkedList支持序列化,通过序列化传输,同时LinkedList是非同步的

LinkedList类简介

LinkedList内部是通过链表这中数据来实现数据存储和操作的、所以类简介分为两部分、第一部分是关于链表的简介,第二部分LinkedList类的简介
概念:
如果一个节点包含指向另一个节点的数据值,那么多个节点可以链接成一串,只通过一个变量访问整个节点序列,这样的节点序列称为链表、
单向链表:
如果节点仅包含向后继节点的引用,这样的链表称为单向链表。
双向链表:
链表节点,包含两个引用,一个指向前驱节点,一个指向后驱节点。
关键属性:
//实际存储的元素个数
transient int size = 0;
//头节点
transient Node<E> first;
//尾部节点
transient Node<E> last;

节点类:
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
public LinkedList(){

 //构造指定集合的LinkedList,并且按集合迭代的元素顺序排序
public LinkedList(Collection<? extends E> c){
  this();
  addAll(c);


}

插入元素:
插入单个元素的方法主要有boolean add(E e)和 void add(int index,E element)
boolean add(E e):表示将指定元素插入到LinkedList尾部,插入链表尾部调用的方法是linkLast(E e).
public boolean add(E e){
   linkLast(e);//插入尾部
   return true;
}

void linkLast(E e){//插入LinkedList的尾部
   final Node<E> l =last;
   //新建一个节点,前一个节点时原来的尾节点,下一个节点为null
   final Node<E> newNode = new Node<>(l,e,null);
   last = newNode;//将新建的节点为尾节点
  if(l == null)
      first = newNode;//空LinkList
  else
     l.next = newNode;
 size++;
 modeCount++;


}
void add(int index,E element) :表示将指定元素插入到index位置处。如果插入的位置在链表尾部,直接插入到链表尾部;如果插入的位置不再链表尾部,要调用的方法是linkBefore(E e,Node<E> succ),还需要调用node(int index)获得某位置上的元素。

public void add(int index, E element) {
      checkPositionIndex(index);//判断位置的范围


      if (index == size)
          linkLast(element);//插入尾部
      else
          linkBefore(element, node(index));//将元素插入到index位置节点之前
  }


   void linkBefore(E e, Node<E> succ) {//将元素插入到succ节点前
      // assert succ != null;
      final Node<E> pred = succ.prev;//获取succ前一个节点
      final Node<E> newNode = new Node<>(pred, e, succ);//创建新节点,插入到pred和succ之间
      succ.prev = newNode;//改变succ的前一个节点的引用
      if (pred == null)
          first = newNode;//LinkedList只有一个元素
      else
          pred.next = newNode;
      size++;
      modCount++;
  }


  Node<E> node(int index) {//获取index位置上的节点
      // assert isElementIndex(index);
      if (index < (size >> 1)) {//index小于size的一半,从前往后找
          Node<E> x = first;
          for (int i = 0; i < index; i++)
              x = x.next;
          return x;
      } else {//index大于size的一半,从后往前找
          Node<E> x = last;
          for (int i = size - 1; i > index; i--)
              x = x.prev;
          return x;
      }
  }
删除:
删除元素方法主要有E remove(int index)、boolean remove(Object o)和实现Deque接口中的E remove().
E remove()
E remove(int index)表示删除索引位置上的元素,boolean remove(Object o)表示删除首次出现的指定元素,都会调用unlink(Node<E> x)
//删除索引位置上的元素
  public E remove(int index) {
      checkElementIndex(index);//防止越界
      return unlink(node(index));
  }


  //移除首次出现的指定元素
  public boolean remove(Object o) {
      if (o == null) {//元素为null
          for (Node<E> x = first; x != null; x = x.next) {
              if (x.item == null) {
                  unlink(x);
                  return true;
              }
          }
      } else {
          for (Node<E> x = first; x != null; x = x.next) {
              if (o.equals(x.item)) {
                  unlink(x);
                  return true;
              }
          }
      }
      return false;
  }


  E unlink(Node<E> x) {//删除节点x
      // assert x != null;
      final E element = x.item;
      final Node<E> next = x.next;//要删除节点的后一个节点
      final Node<E> prev = x.prev;//要删除节点的前一个节点


      if (prev == null) {//x为头节点
          first = next;
      } else {
          prev.next = next;
          x.prev = null;//释放x的前节点的引用
      }


      if (next == null) {//x为尾节点
          last = prev;
      } else {
          next.prev = prev;
          x.next = null;//释放x的后节点的引用
      }


      x.item = null;
      size--;
      modCount++;
      return element;
  }

ArrayList插入、删除操作时,查找到该位置的元素迅速,但是复制元素消耗时间
LinkedList插入、删除操作时,查找需要操作的Entry元素需要消耗一定时间,但改变该节点前后引用地址快速


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值