java容器类详解--LinkedList
2017-02-14 17:12
232 查看
LinkedList的主要特点是它实现了List,Deque,可以作为堆栈,队列,双端队列,以及链表
内部维护了一个内部类Entry
链表的最后一个元素的下一个元素就是header,header的前一个元素就是链表的最后一个元素,这样就形成了环形链表了。注意:LinkedList的index是从0开始,并且不算header在内
LinkedList的增删改查都是围绕这一串链表进行的操作
添加单个元素:LinkedList中的添加单个元素都是调用的同一个方法addBefore()
添加一个集合:在指定索引位置添加集合addAll(int index, Collection
删除元素:所有的删除方法都是调用的它的一个私有方法
根据索引查找元素:entry(int index)
修改元素和查询元素的方法比较简单,这里就不一一列举。
因为linkedList可以作为队列/双端队列使用,可以使用offer()、poll()等一系列对链表的头尾元素的操作方式。
对于普通的实现了Iterator接口的类来说,仅仅之后单向迭代,而LinkedList比较特殊,它的listIterator()方法会返回一个它的内部类,这个内部类实现Iterator,并扩展了向前迭代的功能,在每次next()执行时,会保存上一次的元素。
虽然LinkedList中的listIterator()和listIterator(int index)是两个方法,其实listIterator()是abstractList中的方法,然后调用了其同类方法listIterator(int index) 因为LinkedList重写了listIterator(),所以还是调用的是LinkedList中的listIterator方法。
内部维护了一个内部类Entry
//私有静态内部类,笔者个人认为class前面加不加静态属性,影响不大 private static class Entry<E> { E element; Entry<E> next; Entry<E> previous; //构造器中传入元素本身的引用,以及下一个、上一个元素的引用 Entry(E element, Entry<E> next, Entry<E> previous) { this.element = element; this.next = next; this.previous = previous; } }
链表的最后一个元素的下一个元素就是header,header的前一个元素就是链表的最后一个元素,这样就形成了环形链表了。注意:LinkedList的index是从0开始,并且不算header在内
LinkedList的增删改查都是围绕这一串链表进行的操作
添加单个元素:LinkedList中的添加单个元素都是调用的同一个方法addBefore()
private Entry<E> addBefore(E e, Entry<E> entry) { //先组装好即将添加的元素 Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); //将原来的链路打断,接入新的元素 newEntry.previous.next = newEntry; newEntry.next.previous = newEntry; size++; /** modCount表示这个链表发生结构性的变化的次数,在调用listIterator()遍历元素的时候(生成的ListItr 对象会记录当时的LInkedList的modCount),如果在遍历的同事,调用LinkedList的增加和删除方法 modCount发生改变就会抛出ConcurrentModificationException */ modCount++; return newEntry; }
添加一个集合:在指定索引位置添加集合addAll(int index, Collection
public boolean addAll(int index, Collection<? extends E> c) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Object[] a = c.toArray(); int numNew = a.length; if (numNew==0) return false; modCount++; //保存下一个元素的引用 Entry<E> successor = (index==size ? header : entry(index)); //保存上一个元素的引用 Entry<E> predecessor = successor.previous; for (int i=0; i<numNew; i++) { Entry<E> e = new Entry<E>((E)a[i], successor, predecessor); //将predecessor中的"下一个元素引用"改为新元素 predecessor.next = e; //将前一个元素向后移一位 predecessor = e; } //循环结束之后将后一个元素的"前一个元素"由最开始的previous改为最后的predecessor successor.previous = predecessor; size += numNew; return true; }
删除元素:所有的删除方法都是调用的它的一个私有方法
private E remove(Entry<E> e) { if (e == header) throw new NoSuchElementException(); E result = e.element; //打断链条,重新接上新的元素 e.previous.next = e.next; e.next.previous = e.previous; //置为null,等待gc回收 e.next = e.previous = null; e.element = null; size--; modCount++; return result; }
根据索引查找元素:entry(int index)
private Entry<E> entry(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Entry<E> e = header; //由于链表的特性,遍历元素时要根据上一个元素才能得到下一个元素,所以程序先将index与size的一半进行判断,减少遍历的次数 if (index < (size >> 1)) { for (int i = 0; i <= index; i++) e = e.next; } else { for (int i = size; i > index; i--) e = e.previous; } return e; }
修改元素和查询元素的方法比较简单,这里就不一一列举。
因为linkedList可以作为队列/双端队列使用,可以使用offer()、poll()等一系列对链表的头尾元素的操作方式。
对于普通的实现了Iterator接口的类来说,仅仅之后单向迭代,而LinkedList比较特殊,它的listIterator()方法会返回一个它的内部类,这个内部类实现Iterator,并扩展了向前迭代的功能,在每次next()执行时,会保存上一次的元素。
虽然LinkedList中的listIterator()和listIterator(int index)是两个方法,其实listIterator()是abstractList中的方法,然后调用了其同类方法listIterator(int index) 因为LinkedList重写了listIterator(),所以还是调用的是LinkedList中的listIterator方法。
虽然是链表结构,插入元素和删除元素比较快,但是在插入和删除元素之前需要定位元素,只能从头/尾挨个遍历,这样效率就比较慢,特别是操作链表中间的元素的时候。
相关文章推荐
- Java中的ArrayList 、List、LinkedList、Collection关系详解
- java集合(ArrayList,Vector,LinkedList,HashSet,TreeSet的功能详解)
- java的LinkedList详解
- java中的ArrayList 、List、LinkedList、Collection关系详解
- java中的ArrayList 、List、LinkedList、Collection关系详解
- 用java源代码学数据结构<四>: LinkedList 详解
- Java中 ArrayList、Vector和LinkedList 的使用和详解(转)
- java LinkedList源码详解及实例
- 详解Java中ArrayList、Vector、LinkedList三者的异同点
- 详解Java中ArrayList、Vector、LinkedList三者的异同点
- Java容器类List、ArrayList、Vector及map、HashTable、HashMap、TreeMap、LinkedHashap的区别与用法
- Java集合之ArrayList和LinkedList的实现原理以及Iterator详解
- Java的LinkedList详解,看源码之后的总结
- 【转载】java中的ArrayList 、List、LinkedList、Collection关系详解
- java集合(ArrayList,Vector,LinkedList,HashSet,TreeSet的功能详解)
- JAVA详解双向循环链表(参照java.util.LinkedList)
- Java集合:LinkedList使用详解及源码分析
- Java LinkedList的实现原理详解
- java集合LinkedList的底层实现源码详解
- Java中LinkedList详解和使用示例_动力节点Java学院整理