Conllection之LinkedList源码简析
来源:互联网 发布:软件销售企业财务处理 编辑:程序博客网 时间:2024/06/04 00:24
简单模拟一下单链表增删改原理
public class Demo{ //必须有一个根节点root public static Node root ; //插入节点 public static void insertNode(Node node){ //先找到最后一个尾节点,再将next指向一个新的节点 //插入之前判断根节点时候为空,若为空,则把这个节点作为头结点 Node current=null; if(root==null){ root=node; return; } current=root; Node pNode; while((pNode=current.getNext())!=null){ current=pNode; }//pNode如果为空则应该将这个node插入到这个Node current.setNext(node); } //遍历节点 public static Node getAllNode(){ Node pNode; Node current=root; while((pNode=current.getNext())!=null){ System.out.println(current.getData()); current=pNode; } System.out.println(current.getData()); return root; } //删除节点 public static void deleteNode(String node){ Node pNode; Node current=root; while((pNode=current.getNext())!=null){ //判断当前指针的下一跳指针的值是否和要删除的数相等,如果相等,则将下一跳的指针断开,由当前指针指向下下一条指针的数据,将下一跳指针的链断开 if(pNode.getData().equals(node)){ Node pNodeNext=pNode.getNext();//这是下下一条指针的数据 current.setNext(pNodeNext);//重新设置当前指针指向下一跳 pNode.setNext(null);//断开下一跳指针的链 return; } } } //修改节点 public static void updateNode(String orginNode,String desNode) throws Exception{ //防止空指针异常,自定义异常 if(orginNode==null){ throw new Exception("原始数据不能为空"); } Node pNode; Node current=root; while((pNode=current.getNext())!=null){ //根节点不保存数据 if(orginNode.equals(current.getData())){//这是使用xxx.equals(对象名xxx),确定调用的对象不为空 //这里需要使用当前节点,若使用pNode会忽略第一个当前数据 current.setData(desNode); break; } current=pNode; } } public static void main(String[] args) throws Exception { Node node1=new Node(); Node node2=new Node(); Node node3=new Node(); node1.setData("1"); node2.setData("2"); node3.setData("3"); insertNode(node1); insertNode(node2); insertNode(node3); //deleteNode("2"); updateNode("1", "11"); getAllNode(); }}class Node{ private String data; public String getData() { return data; } public void setData(String data) { this.data = data; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } private Node next;}
LinkedList是一个双向链表,如何体现出来的呢?
左边是LinkedList的继承体系,右边是LinkedList的一些方法
LinkedList继承了AbstractSequentialList实现了Deque,
AbstractSequentialList继承自AbstractList,他的功能主要是为顺序存储结构如链表提供一个最小实现的接口框架实现
Deque< E >是一个线性集合支持插入删除在两端,全称为“double ended queue”双端队列,由此可以看出,这个Deque为LinkedList支持其底层双向链表的操作
这里介绍几个方法,linkedList添加的方法默认是向尾节点插入调用linkLast(e)方法 public void addLast(E e) {
linkLast(e);
}
首先这里first和last的定义
/** * Pointer to first node. * Invariant: (first == null && last == null) || * (first.prev == null && first.item != null) */ transient Node<E> first; /** * Pointer to last node. * Invariant: (first == null && last == null) || * (last.next == null && last.item != null) */ transient Node<E> last;`
从这里看出first和last是作为一个指针,指向第一个和最后一个节点
/** * Links e as last element. */ void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null);//l表示前一个节点,e表示添加的元素,null表示下一个节点 last = newNode;//将添加的节点赋给上一个节点 if (l == null)//这里的l表示上一个节点 first = newNode;//如果是null,将新节点作为首节点-header else l.next = newNode;//如果不是,将l的next指向newNode,而newNode(l,e,null)中的l指向上一个节点,这样就实现了l的next指向newNode的prev,newNode的prev指向l的next size++;//增加linkedlist的长度 modCount++;//增加linkedlist修改的次数 }
在源码中Node作为内部类,其中next为后继,prev是前驱
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; } }
remove方法解析
public boolean remove(Object o) { if (o == null) {//判断要删除的这个对象o for (Node<E> x = first; x != null; x = x.next) //遍历这个linkedlist,从首节点开始知道尾节点的next指向null { if (x.item == null) {//item表示节点的元素, unlink(x);//unlink的方法是真正执行删除操作的方法,它的作用是从底层将要删除的节点两端的断开,然后将前后两个节点连接起来 return true; } } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; }
unlink(Node< E > x)源码如下
/** * Unlinks non-null node x. */ E unlink(Node<E> x) { // assert x != null; final E element = x.item;//当前节点的元素 final Node<E> next = x.next;//表示当前节点的下一个节点 final Node<E> prev = x.prev;//当前节点的上一个节点 if (prev == null) { first = next;//若prev为空,则将next作为首节点,删除本来为首节点的当前节点 } else { prev.next = next;//若不为空,将prev的下一节点指向next x.prev = null;//将x的prev的节点断开 } if (next == null) { last = prev;//若next为空,将prev设置为尾节点,删除本为尾节点的当前节点 } else { next.prev = prev;//若不为空,将next节点的上一个节点指向prev x.next = null;//设置x的next为空,断开x的next链 } x.item = null;//将x的值设置为空 size--;//将linkedlist的大小相应缩小 modCount++;//修改次数依次增加 return element; }
阅读全文
0 0
- Conllection之LinkedList源码简析
- Conllection
- Java8 LinkedList源码简析
- 源码分析之LinkedList
- Java源码之LinkedList
- 源码分析之LinkedList
- Java源码之LinkedList
- Java基础--集合框架Conllection(LinkedList、ArrayList)
- java源码分析之LinkedList
- JDK源码阅读之LinkedList
- jdk集合源码之LinkedList
- java源码分析之LinkedList
- Java源码分析之LinkedList
- java源码分析之LinkedList
- java源码分析之LinkedList
- java源码分析之LinkedList
- Java源码阅读之LinkedList
- Java源码分析之LinkedList
- 612. K个最近的点[LintCode]
- [uboot] uboot启动kernel篇(三)——uboot解析uImage的kernel信息
- vue使用图表类2 柱形图表
- 一道凑数问题
- Spring是如何加载Xml文件的
- Conllection之LinkedList源码简析
- 创建maven web项目 pom报错:Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war
- BZOJ2588 主席树
- C语言实验——余弦
- 11月24号 Gson
- Java浮点数float,bigdecimal和double精确计算的精度误差问题总结
- laravel5 列出所有事件 和事件实例
- jodd-html学习
- 女娲刺秦/易水副本脚本