android 集合架构四- LinkedList
2015-08-12 11:48
543 查看
直接上源码,通过阅读源码,我们自然就知道LinkedList实现的原理
上面是实现了自己的遍历Iterator,有点类似指针
默认添加一个集合主要还是看addAll 方法
添加集合,首先检验这个集合的长度,假如为0 返回false,取最后一个不为null的previous ,然后在 循环里面,new 一个新的newLink,把 newlink 赋值为 previous.next,然后再把newlink赋值给previous ,这样就能再下次循环中给newlink的next复制了,循环结束后,赋值最后一个为voidLink,此时size 以及相关变量也修改。
首先要明白,LinkedList 是一环形的链表,最后的voidLink.next 指向首link,所以计算一下location的位置,是偏前还是偏后,假如是在前半列,直接使用voidLink的next 去寻找要添加位置当前的link,假如是在后半列,使用voidLink的 previous,这样可以减少寻找的次数。
在特定位置添加集合,还是得找到此刻特定位置的link,逻辑和上面相同,略过...
在列表头加入数据,上面已经提过,此列表是一个环形的列表,应该利用 voieLink.next 就是第一条数据
删除特定位置的元素,这个也是根据voidLink 来寻找在特定位置的数据
方法就不再一一列举了,LinkedList 原理是一个环形的闭合链表,并且我们是通过最后一条数据来寻找特定位置的数据,无论是增删改查都是通过voidLink这个元素来遍历元素的,和ArrsyList比较 查找数据比较慢,但是添加和删除数据是较快的。
private static final class Link<ET> { ET data; Link<ET> previous, next; Link(ET o, Link<ET> p, Link<ET> n) { data = o; previous = p; next = n; } }使用结点来存储数据
private static final class LinkIterator<ET> implements ListIterator<ET> { int pos, expectedModCount; final LinkedList<ET> list; Link<ET> link, lastLink; LinkIterator(LinkedList<ET> object, int location) { list = object; expectedModCount = list.modCount; if (location >= 0 && location <= list.size) { // pos ends up as -1 if list is empty, it ranges from -1 to // list.size - 1 // if link == voidLink then pos must == -1 link = list.voidLink; if (location < list.size / 2) { for (pos = -1; pos + 1 < location; pos++) { link = link.next; } } else { for (pos = list.size; pos >= location; pos--) { link = link.previous; } } } else { throw new IndexOutOfBoundsException(); } } public void add(ET object) { if (expectedModCount == list.modCount) { Link<ET> next = link.next; Link<ET> newLink = new Link<ET>(object, link, next); link.next = newLink; next.previous = newLink; link = newLink; lastLink = null; pos++; expectedModCount++; list.size++; list.modCount++; } else { throw new ConcurrentModificationException(); } } public boolean hasNext() { return link.next != list.voidLink; } public boolean hasPrevious() { return link != list.voidLink; } public ET next() { if (expectedModCount == list.modCount) { LinkedList.Link<ET> next = link.next; if (next != list.voidLink) { lastLink = link = next; pos++; return link.data; } throw new NoSuchElementException(); } throw new ConcurrentModificationException(); } public int nextIndex() { return pos + 1; } public ET previous() { if (expectedModCount == list.modCount) { if (link != list.voidLink) { lastLink = link; link = link.previous; pos--; return lastLink.data; } throw new NoSuchElementException(); } throw new ConcurrentModificationException(); } public int previousIndex() { return pos; } public void remove() { if (expectedModCount == list.modCount) { if (lastLink != null) { Link<ET> next = lastLink.next; Link<ET> previous = lastLink.previous; next.previous = previous; previous.next = next; if (lastLink == link) { pos--; } link = previous; lastLink = null; expectedModCount++; list.size--; list.modCount++; } else { throw new IllegalStateException(); } } else { throw new ConcurrentModificationException(); } } public void set(ET object) { if (expectedModCount == list.modCount) { if (lastLink != null) { lastLink.data = object; } else { throw new IllegalStateException(); } } else { throw new ConcurrentModificationException(); } } }
上面是实现了自己的遍历Iterator,有点类似指针
private class ReverseLinkIterator<ET> implements Iterator<ET> { private int expectedModCount; private final LinkedList<ET> list; private Link<ET> link; private boolean canRemove; ReverseLinkIterator(LinkedList<ET> linkedList) { list = linkedList; expectedModCount = list.modCount; link = list.voidLink; canRemove = false; } public boolean hasNext() { return link.previous != list.voidLink; } public ET next() { if (expectedModCount == list.modCount) { if (hasNext()) { link = link.previous; canRemove = true; return link.data; } throw new NoSuchElementException(); } throw new ConcurrentModificationException(); } public void remove() { if (expectedModCount == list.modCount) { if (canRemove) { Link<ET> next = link.previous; Link<ET> previous = link.next; next.next = previous; previous.previous = next; link = previous; list.size--; list.modCount++; expectedModCount++; canRemove = false; return; } throw new IllegalStateException(); } throw new ConcurrentModificationException(); } }此类是倒叙遍历,倒叙删除集合
/** * Constructs a new empty instance of {@code LinkedList}. */ public LinkedList() { voidLink = new Link<E>(null, null, null); voidLink.previous = voidLink; voidLink.next = voidLink; }给最后一个节点赋值
public LinkedList(Collection<? extends E> collection) { this(); addAll(collection); }
默认添加一个集合主要还是看addAll 方法
@Override public boolean addAll(Collection<? extends E> collection) { int adding = collection.size(); if (adding == 0) { return false; } Collection<? extends E> elements = (collection == this) ? new ArrayList<E>(collection) : collection; Link<E> previous = voidLink.previous; for (E e : elements) { Link<E> newLink = new Link<E>(e, previous, null); previous.next = newLink; previous = newLink; } previous.next = voidLink; voidLink.previous = previous; size += adding; modCount++; return true; }
添加集合,首先检验这个集合的长度,假如为0 返回false,取最后一个不为null的previous ,然后在 循环里面,new 一个新的newLink,把 newlink 赋值为 previous.next,然后再把newlink赋值给previous ,这样就能再下次循环中给newlink的next复制了,循环结束后,赋值最后一个为voidLink,此时size 以及相关变量也修改。
public void add(int location, E object) { if (location >= 0 && location <= size) { Link<E> link = voidLink; if (location < (size / 2)) { for (int i = 0; i <= location; i++) { link = link.next; } } else { for (int i = size; i > location; i--) { link = link.previous; } } Link<E> previous = link.previous; Link<E> newLink = new Link<E>(object, previous, link); previous.next = newLink; link.previous = newLink; size++; modCount++; } else { throw new IndexOutOfBoundsException(); } }
首先要明白,LinkedList 是一环形的链表,最后的voidLink.next 指向首link,所以计算一下location的位置,是偏前还是偏后,假如是在前半列,直接使用voidLink的next 去寻找要添加位置当前的link,假如是在后半列,使用voidLink的 previous,这样可以减少寻找的次数。
public boolean add(E object) { return addLastImpl(object); } private boolean addLastImpl(E object) { Link<E> oldLast = voidLink.previous; Link<E> newLink = new Link<E>(object, oldLast, voidLink); voidLink.previous = newLink; oldLast.next = newLink; size++; modCount++; return true; }默认添加数据,是添加在列表的末尾的位置
<pre name="code" class="java"> public boolean addAll(int location, Collection<? extends E> collection) { if (location < 0 || location > size) { throw new IndexOutOfBoundsException(); } int adding = collection.size(); if (adding == 0) { return false; } Collection<? extends E> elements = (collection == this) ? new ArrayList<E>(collection) : collection; Link<E> previous = voidLink; if (location < (size / 2)) { for (int i = 0; i < location; i++) { previous = previous.next; } } else { for (int i = size; i >= location; i--) { previous = previous.previous; } } Link<E> next = previous.next; for (E e : elements) { Link<E> newLink = new Link<E>(e, previous, null); previous.next = newLink; previous = newLink; } previous.next = next; next.previous = previous; size += adding; modCount++; return true; }
在特定位置添加集合,还是得找到此刻特定位置的link,逻辑和上面相同,略过...
public void addFirst(E object) { addFirstImpl(object); } private boolean addFirstImpl(E object) { Link<E> oldFirst = voidLink.next; Link<E> newLink = new Link<E>(object, voidLink, oldFirst); voidLink.next = newLink; oldFirst.previous = newLink; size++; modCount++; return true; }
在列表头加入数据,上面已经提过,此列表是一个环形的列表,应该利用 voieLink.next 就是第一条数据
@Override public void clear() { if (size > 0) { size = 0; voidLink.next = voidLink; voidLink.previous = voidLink; modCount++; } }清理数据,只需要把voidLink 的previous 和next 赋值为null 就可以了
@Override public E remove(int location) { if (location >= 0 && location < size) { Link<E> link = voidLink; if (location < (size / 2)) { for (int i = 0; i <= location; i++) { link = link.next; } } else { for (int i = size; i > location; i--) { link = link.previous; } } Link<E> previous = link.previous; Link<E> next = link.next; previous.next = next; next.previous = previous; size--; modCount++; return link.data; } throw new IndexOutOfBoundsException(); } @Override public boolean remove(Object object) { return removeFirstOccurrenceImpl(object); }
删除特定位置的元素,这个也是根据voidLink 来寻找在特定位置的数据
方法就不再一一列举了,LinkedList 原理是一个环形的闭合链表,并且我们是通过最后一条数据来寻找特定位置的数据,无论是增删改查都是通过voidLink这个元素来遍历元素的,和ArrsyList比较 查找数据比较慢,但是添加和删除数据是较快的。
相关文章推荐
- 软件架构设计应该考虑的问题(优秀)
- 提升网站页面打开速度的12个建议
- 软件架构和设计
- 对软件架构的理解杂记
- 对概念性架构设计的理解杂记(优秀)
- 软件架构设计---基于鲁棒图进行设计
- 架构、框架和设计模式关系(转)
- android 集合架构三- ArrayList
- 如何告知用户以及蜘蛛网站正在维护?
- 游戏架构脚本该如何来写
- 如何给网站添加内部链接
- Web网站的性能测试工具
- VO(DTO)模式在架构设计中是否需要
- ALSA(高级Linux声音架构):一 简单例子
- DNSPod--国内最早提供免费智能DNS产品的网站,致力于为各类网站提供高质量的多线智能DNS免费解析
- iOS应用架构谈(一):架构设计的方法论
- 基金公司官方网站设计建设
- 一些好的技术博客知识和网站
- 伪静态网站分享到微信链接打不开的解决办法
- 高负载web架构(三)