四、链表功能完善(增加迭代器)

有些话、适合烂在心里 提交于 2020-01-29 03:13:18

要想使用迭代器或者foreach输出链表元素,那么就要实现Iterable接口
然后定义一个内部类实现Iterator接口
一共重写3个方法 这个链表就可以使用迭代器输出了 也就可以使用foreach了

class LinkImpl<T> implements ILink<T>,Iterable<T> {


    @Override
    public Iterator<T> iterator() {
        return new LinkImplIter();
    }

    private class LinkImplIter implements Iterator{
        int cursor = 0; //指针从0开始

        @Override
        public boolean hasNext() {

            return cursor != size(); //此时还有内容
        }

        @Override
        public Object next() {
                try {
                    int i = cursor;
                    T next = get(i);
                    cursor = i + 1;
                    return next;
                } catch (IndexOutOfBoundsException e) {
                    e.printStackTrace();
                }

            return next();
        }



    }
    //==========以上实现foreach输出链表内容================

    private class Node<T> {
        private T data;
        private Node<T> next;

        public Node(T data) {
            this.data = data;
        }

        //第1次调用方法:this=LinkImpl.root;
        //第2次调用方法:this=LinkImpl.root.next;
        //第3次调用方法:this=LinkImpl.root.next.next;
        //...

        //增
        public void addNode(Node<T> newNode) {
            if (this.next == null) { //当前节点之后有空余
                this.next = newNode;
            } else {
                this.next.addNode(newNode);
            }
        }

        //获取全部数据组成的对象数组
        public void toArrayNode() {
            LinkImpl.this.returnData[LinkImpl.this.foot++] = this.data; //获取当前节点数据
            if (this.next != null) {
                this.next.toArrayNode(); //递归调用
            }
        }

        //根据索引获取对应元素
        public T getNode(int index) {
            if (LinkImpl.this.foot++ == index) { //索引相同 返回当前数据
                return this.data; //返回当前数据
            } else {
                if (this.next != null) {
                    return this.next.getNode(index);
                } else { //到最后了
                    return null;
                }
            }
        }

        //根据索引修改元素值
        public T setNode(int index, T newData) {
            if (LinkImpl.this.foot++ == index) {
                T temp = this.data; //返回数据
                this.data = newData;
                return temp;
            } else {
                if (this.next != null) {
                    return this.next.setNode(index, newData);
                } else {
                    return null;
                }

            }
        }

        //查找指定元素是否存在
        public boolean containsNode(T data) {
            if (this.data.equals(data)) { //数据判断相同
                return true;
            } else {
                if (this.next != null) {
                    return this.next.containsNode(data);
                } else {
                    return false;
                }

            }
        }

        //删除指定元素
        public void removeNode(Node<T> previous, T data) {
            if (this.data.equals(data)) {
                previous.next = this.next; //空出当前节点
            } else {
                if (this.next != null) { //还有后续节点
                    this.next.removeNode(this, data);
                }
            }

        }


    }


    //==============以上为内部的节点关系类==================
    private Node<T> root; //根节点
    private int count; //统计元素个数
    private int foot; //索引角标
    private Object[] returnData; //返回数组

    @Override
    public void add(T data) {
        if (data == null) {  //排除掉所有的空元素
            return;
        }
        Node<T> newNode = new Node<T>(data); // 将数据封装在节点中
        if (this.root == null) {  // 没有根节点
            this.root = newNode;
        } else {        //此时根节点存在
            this.root.addNode(newNode);  //交由Node类处理
        }

        this.count++;

    }


    @Override
    public int size() { //获取链表内存储元素的个数
        return this.count;
    }

    @Override
    public boolean isEmpty() {
        //  return this.count==0;   //建议使用下面的方式 调用size()方法
        return this.size() == 0;
    }

    @Override
    public Object[] toArray() {
        if (this.size() == 0) { //没有元素则返回空
            return null;
        }
        this.foot = 0;  //角标清零
        this.returnData = new Object[this.size()];
        this.root.toArrayNode(); //交给Node类负责处理
        return this.returnData;  //返回处理结果
    }

    @Override
    public T get(int index) {
        if (index >= this.size() || index < 0) {
            return null;
        }
        this.foot = 0; //foot清0
        return this.root.getNode(index); //交由Node类处理

    }

    @Override
    public T set(int index, T newData) {
        if (index >= this.size() || index < 0) {
            return null;
        }
        this.foot = 0;
        return this.root.setNode(index, newData);
    }

    @Override
    public boolean contains(T data) {
        if (this.size() == 0 || data == null) {
            return false;
        } else {
            return this.root.containsNode(data);
        }

    }

    @Override
    public void remove(T data) {

        if (this.size() == 0 || data == null) {
            return;
        }
        if (this.root.data.equals(data)) { //根节点
            this.root = this.root.next; //修改根节点

        } else { //后续判断可以从第二个节点开始
            if (this.root.next != null) {
                this.root.next.removeNode(this.root, data);
            }
        }
        count--;

    }

    @Override
    public void clear() {
        this.root = null; //清空所有引用
        this.count = 0;
    }


}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!