java实现链表(模拟LinkedList)

 众所周知,链表是由一个个节点连接在一起,这里我们就先创建一个节点类,为了达到模拟效果,我们选择建一个Node的静态内部类。

我们要想模拟LinkedList,就得先了解LinkedList的类包含的方法:

 add(Object)   dd(int,Object)   addFirst   addLast   get(int index)   remove    getIndex  removeFirst  removeLast等

以及LinkedList 所实现的接口:


    

我们为了要使用foreach语句遍历,就必须实现Iterable接口。附上代码:

import java.util.Iterator;
public class MyLinkedList<T> implements Iterable<T>{
    private Node<T> first;//指向第一个节点的工作指针
    private Node<T> current;//指向最后一个节点的工作指针
    private int size=0;//统计链表长度
    private static class Node<T>{
        T data;
        Node<T> next;
    }
    //获取长度
    public int size(){
        return size;
    }
    //添加节点
    public void add(T data){
        Node<T> newNode=new Node<T>();
        newNode.data=data;
        
        if(first==null){
            first=newNode;
            current=newNode;
            size++;
            return;
        }
        current.next=newNode;
        current=newNode;
        size++;
    }
    //插入第一个位置
    public void addFirst(T data){
        Node<T> newNode=new Node<T>();
        newNode.data=data;
        
        if(first==null){
            first=newNode;
            current=newNode;
            size++;
            return;
        }
        newNode.next=first;
        first=newNode;
        size++;
    }
    public void addLast(T data){
        add(data);
    }
    //根据索引添加节点
    public void add(int index,T data){
        Node<T> newNode=new Node<T>();
        newNode.data=data;        
        
        Node node=getNode(index);//指向指定索引之前的节点        
        
        if(node==null){
            addFirst(data);
            return;
        }
        newNode.next=node.next;
        node.next=newNode;
        size++;
    }
    /**
     * 得到指定索引的数据
     * @param index
     * @return 数据
     */
    public T get(int index){
        return getNode(index).next.data;
    }
    /**
     * 得到指定索引的前一个节点
     * @param index
     * @return
     */
    private Node<T> getNode(int index) {
        Node<T> node=null;
        if(index==0){
            //插入到第一个
            return null;
        }
        if(index<size){
            //插入中间
            node=first;
            for(int i=1;i<index;i++){
                node=node.next;
            }
            return node;
        }
        return current;
    }
    /**
     * 迭代器
     */
    public Iterator<T> iterator(){
        return new Iterator<T>() {
            Node<T> cur;
            @Override
            public boolean hasNext() {
                if(cur==null && first!=null){
                    cur=first;
                    return true;
                }
                if(cur.next!=null){
                    cur=cur.next;
                    return true;
                }
                return false;
            }
            @Override
            public T next() {
                return cur.data;
            }
        };
    }
    /**
     * 移除数据
     * @param data
     */
    public void remove(T data){
        //查找数据的索引
        int index=getIndex(data);
        remove(index);
    }
    /**
     * 通过数据查找第一次出现的索引
     * @param data
     * @return
     */
    private int getIndex(T data) {
        Node node=first;
        for(int i=0;i<size;i++){
            if(node.data.equals(data)){
                return i;
            }
            node=node.next;
        }
        return -1;
    }
    /**
     * 移除指定索引的数据
     * @param index
     */
    public void remove(int index){
        Node prev=getNode(index);
        Node node=getNode(index+1);
        prev.next=node.next;
        size--;
    }
    /**
     * 移除第一个
     */
    public void removeFirst(){
        first=first.next;
        size--;
    }
    /**
     * 移除最后一个
     */
    public void removeLast(){
        //查找倒数第二个节点
        Node node=getNode(size-1);
        node.next=null;
        current=node;
        size--;
    }
    /**
     * 修改指定索引的数据
     * @param index
     * @param newData
     */
    public void set(int index,T newData){
        //得到指定索引节点
        Node node=getNode(index+1);
        if(node==null){
            node=first;
        }
        //修改节点上的数据
        node.data=newData;
    }
}

到这里我们基本模拟了LinkedList类的所有方法,我们赶紧来测试下:

public class Demo {
    /**
     * @param args
     */
    public static void main(String[] args) {
        MyLinkedList<String> list=new MyLinkedList<String>();
        list.add("AAA");
        list.add("BBB");
        list.add("CCC");
        list.addFirst("DDD");
        list.addLast("EEE");
        list.add(2,"FFF");
        
        for(String s:list){
            System.out.println(s);
        }
        String s=list.get(2);
        System.out.println("下标为2的元素:"+s);
        
        list.set(2, "TEST");
        System.out.println("Size:"+list.size());
        list.removeFirst();
        list.removeLast();
        list.remove(2);
        System.out.println("------------------");
        for(String st:list){
            System.out.println(st);
        }
    }
}

这里我们附上效果图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值