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是一个双向链表,如何体现出来的呢?
在类名上双击选中后右击选择 open Type Hierarchy,之后再左上角有个图标【show the supertype hierarchy】切换到下图
左边是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;    }
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 全民k歌手机话筒有杂音怎么办 手机刷机清除数据需要密码怎么办 oppo手机屏锁密码忘了怎么办 华为手机摔了一下开不了机怎么办 华为v9手机删除隐私空间了怎么办 华为荣耀畅玩5x卡顿怎么办 淘宝买家收到货后恶意退款怎么办 手机淘宝申请退款后不想退了怎么办 买房交首付时的收据发票掉了怎么办 苹果商城消费提示问题忘记了怎么办 psd文件超过2g不能存储怎么办 手机拍的照片做微信头像太大怎么办 上传的照片在等待中传不上去怎么办 淘宝购物车里的图片模糊怎么办 天猫超市一箱饮料少两瓶怎么办 网上卖一件代发顾客要退货怎么办 京东买东西卖家拒绝发货怎么办 淘宝不小心退款给买家了怎么办 不小心智能清理了淘宝物流怎么办 移动卡绑定了太多东西换联通怎么办 淘宝上卖出的东西快递弄丢了怎么办 京东第三方不确认收货怎么办? 天猫评价被判定为广告怎么办 天猫一个订单用卷分单退货怎么办 天猫对已付款成功后自动退款怎么办 拼多多新人红包减价卖家怎么办 魔力宝贝手机版注册人数已满怎么办 买家投诉虚假签收淘宝卖家该怎么办 手机淘宝商家老打骚扰电话怎么办 手机上查询详单忘记服务密码怎么办 淘宝上的东西买过就找不到了怎么办 刚刚开的淘宝企业店没有流量怎么办 有图片怎么在淘宝找不到商品怎么办 白色高跟鞋鞋面磨脏了怎么办弄干净 我跟鞋后跟磨烂的脚怎么办? 内衣买回来有一股刺鼻的味道怎么办 裁剪袖子开口偏了1公分怎么办 对于这乱扔垃圾不听劝者该怎么办 感觉被南通蒲公英店铺骗了怎么办 6个月宝宝吃米粉不吃奶怎么办 十个月的宝宝不吃辅食怎么办