为了账号安全,请及时绑定邮箱和手机立即绑定

ArrayList跟linkList

标签:
Android

 public class LinkedListextends AbstractSequentialListimplements List, Deque, Cloneable, java.io.SerializableLinkedList 是⼀一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列列或双端队列列进⾏行行操作。LinkedList 实现List接⼝口,能对它进⾏行行队列列操作。LinkedList 实现Deque接⼝口,双向队列列,它⽀支持从两个端点⽅方向检索和插⼊入元素。LinkedList 实现了了Cloneable接⼝口,即覆盖了了函数clone(),能克隆隆。LinkedList 实现java.io.Serializable接⼝口,这意味着LinkedList⽀支持序列列化,能通过序列列化去传输。关键字transient 标识的字段的⽣生命周期仅存于调⽤用者的内存中⽽而不不会写到磁盘⾥里里持久化 transient int size = 0;/** * Pointer to first node. * Invariant: (first == null && last == null) || * (first.prev == null && first.item != null) */transient Node first;/** * Pointer to last node. * Invariant: (first == null && last == null) || * (last.next == null && last.item != null) */transient Node last;LinkedList 每个存储元素是⼀一个Node对象LinkedList 源码分析LinkedList 继承结构开始分析LinkedList 属性 private static class Node { E item; Node next; Node prev; Node(Node prev, E element, Node next) { this.item = element; this.next = next; this.prev = prev; }}在这个对象可以分析出.LinkedList 存储开销⽐比Arraylist ⼤大,因为LinkedList每个元素在内存⾥里里多分配了了Nodenext; , Node prev; 两个变量量值.得出.ArrayList 和 LinkedList 存储相同⼤大⼩小的数据. LinkedList 占内存⽐比较⼤大.  public LinkedList(Collection c) { this(); addAll(c); }从 return addAll(size, c);开始分析.参数1.添加位置 , 参数2,需要添加的数据;public boolean addAll(int index, Collection c) { checkPositionIndex(index);  Object[] a = c.toArray(); int numNew = a.length; if (numNew == 0) return false; // 上部分校验数据是否为0 // 但是少了了空指针校验.不不知道是不不是.挖了了坑给我们跳 -------------------------->  Node pred, succ; if (index == size) { //保存index处的节点。插⼊入位置如果是size,则在头结点前⾯面插⼊入,否则在获取index 处的节点插⼊入 succ = null; pred = last; } else { //获取前⼀一个节点,插⼊入时需要修改这个节点的next引⽤用succ = node(index);LinkedList 构造⽅方法 pred = succ.prev; } //可以理理解node摆放的位置 ----------------------------> for (Object o : a) { //在强制类型转换的时候编译器器会给出警告 //@SuppressWarnings("unchecked")此注解去除警告. @SuppressWarnings("unchecked") E e = (E) o; //创建node 参数1.node头 ,参数2.数据 ,参数3.node尾 Node newNode = new Node<>(pred, e, null); if (pred == null) first = newNode; else //修改前⼀一节点的next指针 pred.next = newNode; pred = newNode; }  //收尾的处理理 if (succ == null) { last = pred; } else { pred.next = succ; succ.prev = pred; }  size += numNew; modCount++; return true;}LinkedList 初始化操作会处理理⼀一⼤大坨的.头--尾.地址转换.ArrayList 初始化操作会不不断的copy数组.为了了⾃自增Arrays.copyOf(elementData, size, Object[].class);LinkedList 添加元素  public void add(int index, E element) { checkPositionIndex(index); if (index == size) linkLast(element); else linkBefore(element, node(index));}擦屁股 void linkLast(E e) { final Node l = last; final Node newNode = new Node<>(l, e, null); last = newNode;  if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }按指定位置插  void linkBefore(E e, Node succ) { final Node pred = succ.prev; final Node newNode = new Node<>(pred, e, succ); succ.prev = newNode; if (pred == null) first = newNode; else pred.next = newNode; size++; modCount++;}LinkedList 添加⼜又是处理理头--尾.地址转换ArrayList 添加⼜又会copy数组.为了了⾃自增linkLast ⽅方法linkBefore ⽅方法//Arraylist ⾃自增⻓长 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);  if (newCapacity - minCapacity 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: --------------------------- elementData = Arrays.copyOf(elementData, newCapacity); ---------------------------}public boolean remove(Object o) { if (o == null) { //删除第⼀一个空的元素.、 for (Node x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); return true; } } } else { //查找元素并.删除 for (Node x = first; x != null; x = x.next) { //注意.如果obj.equals(obj)最好重写equals 和 hashCode ⽅方法 if (o.equals(x.item)) { unlink(x); return true; } } } return false;}删除节点把节点的.所有属性指nullLinkedList 删除元素unlink ⽅方法E unlink(Node x) { final E element = x.item; final Node next = x.next; final Node prev = x.prev; if (prev == null) { first = next; } else { //把⾃自⼰己的屁股.指向.上⼀一个的屁股 prev.next = next; //断开头 x.prev = null; } if (next == null) { last = prev; } else { //吧⾃自⼰己的头.指向下⼀一个的头 next.prev = prev; //断开尾 x.next = null; } x.item = null; size--; modCount++; return element;}LinkedList 删除元素.先把⾃自⼰己的东⻄西给别⼈人.然后⾃自⼰己指空.ArrayList 删除元素.还是操作 Copy 数组 public E remove(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); modCount++; E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) //********** //参数1.源数组 //参数2.复制的起始位置 //参数3.⽬目标数组 //参数4.⽬目标数组的位置 //参数5.源数组需要复制的⻓长度 System.arraycopy(elementData, index+1, elementData, index, numMoved); //*********** elementData[--size] = null; // clear to let GC do its work return oldValue;}public E get(int index) { checkElementIndex(index); return node(index).item;}LinkedList 获取元素node ⽅方法 Node node(int index) { // 获取index处的节点。 // 若index > 1)) { Node x = first; for (int i = 0; i x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; }}LinkedList 获取元素.需要⽤用循环找ArrayList 获取元素直接index 下标查找//ArrayList 获取元素public E get(int index) { if (index = this.size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); if (ArrayList.this.modCount != this.modCount) throw new ConcurrentModificationException(); return (E) ArrayList.this.elementData[offset + index]; } 

原文链接:http://www.apkbus.com/blog-340477-76470.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消