【迭代器模式】自己实现一个可以使用增强for循环遍历的链表

自己实现了一个简单的双向链表。

public class LinkedList<T> {
    //起始节点,指向第一个节点
    private Node<T> start;
    //结束节点,指向最后一个节点
    private Node<T> tail;
    //链表长度
    private int length;

    /**
     * 添加元素(尾插)
     * @param data 需要添加进链表的元素
     */
    public void add(T data){
        tailInsert(data);
    }

    /**
     * 添加元素(尾插)
     * @param data 需要添进链表的元素序列
     */
    public void add(T... data){
        tailInsert(data);
    }

    /**
     * 获取元素
     * @param index 元素下标
     * @return 返回下标对应的元素
     */
    public T get(int index){
        //下标越界
        if (length - 1 < index){
            throw new RuntimeException("链表没有那么多元素");
        }

        int i = 0;
        Node<T> res = start;
        while (i++ != index){
            res = res.next;
        }
        return res.data;
    }

    public int size(){
        return length;
    }

    /**
     * 头插
     * @param element 需要插入的数据
     */
    public void startInsert(T element){
        //起始节点替换为新节点
        start = new Node<>(null, element, start);
        //新节点放置在起始节点之前
        if (start.next != null){
            start.next.previous = start;
        }
        //如果尾节点为空,新节点就是尾节点
        if (null == tail){
            tail = start;
        }
        length++;
    }

    /**
     * 批量头插
     * @param elements 需要头插的元素序列
     */
    @SafeVarargs
    public final void startInsert(T... elements){
        //临时链
        Node<T> tempLinkStart = null;
        Node<T> tempLinkTail = null;

        //元素添加到临时链
        for (T element : elements){
            if (null == tempLinkStart && null == tempLinkTail){
                tempLinkStart = new Node<>(null, element, null);
                tempLinkTail = tempLinkStart;
            }else{
                tempLinkStart = tempLinkStart.addPrevious(element);
            }
        }

        //临时链添加到表起始
        if (null != tempLinkTail){
            tempLinkTail.next = start;
            if (null != start){
                start.previous = tempLinkTail;
            }else{
                tail = tempLinkTail;
            }
            start = tempLinkStart;

            length += elements.length;
        }

    }

    /**
     * 尾插
     * @param element 需要插入的数据
     */
    public void tailInsert(T element){
        //替换结束节点
        tail = new Node<>(tail, element, null);
        //放在结束节点之后
        if (tail.previous != null){
            tail.previous.next = tail;
        }
        //如果起始节点为空,新节点就是起始节点
        if (null == start){
            start = tail;
        }
        length++;
    }

    /**
     * 批量尾插
     * @param elements 需要尾插的元素序列
     */
    @SafeVarargs
    public final void tailInsert(T... elements){
        //临时链
        Node<T> tempLinkStart = null;
        Node<T> tempLinkTail = null;

        //元素尾插进入临时链
        for (T element : elements){
            if (null == tempLinkStart && null == tempLinkTail){
                tempLinkStart = new Node<>(null, element, null);
                tempLinkTail = tempLinkStart;
            }else{
                tempLinkTail = tempLinkTail.addNext(element);
            }
        }

        //临时链加入链表
        if (null != tempLinkStart){
            tempLinkStart.previous = tail;
            if (null != tail){
                tail.next = tempLinkStart;
            }else{
                start = tempLinkStart;
            }
            tail = tempLinkTail;

            length += elements.length;
        }
    }




    /**
     * 链表节点类
     */
    static class Node<E>{
        //前驱节点
        Node<E> previous;
        //数据
        E data;
        //后继节点
        Node<E> next;

        Node() {
        }

        Node(Node<E> previous, E data, Node<E> next) {
            this.previous = previous;
            this.data = data;
            this.next = next;
        }

        /**
         * 在本节点之后插入一个元素
         * @param data 需要插入的元素E
         * @return 返回新插入的节点
         */
        Node<E> addNext(E data){
            this.next = new Node<E>(this, data, null);
            return this.next;
        }

        /**
         * 在本节点之前插入一个元素
         * @param data 需要插入的元素
         * @return 返回新插入的节点
         */
        Node<E> addPrevious(E data){
            this.previous = new Node<E>(null, data, this);
            return this.previous;
        }
    }
}

 当测试的时候就遇上了困难。我往链表里面添加了元素以后只能通过get()方法来获取到需要的元素值。

public class TestApp {
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        list.add(1,2,3,4,5);
        for (int i = 0; i < list.size(); i++){
            System.out.println(list.get(i));
        }
    }
}

而官方的LinkedList是可以通过增强for循环来完成遍历的。我也希望通过增强for循环来遍历我自己的链表集合。

我们知道增强for循环底层实际是迭代器完成的。我们就需要用到迭代器模式。

实现迭代器模式的步骤

  1. LinkedList类实现Iterable接口
  2. 写一个LinkedList的迭代器类,实现Iterator<T>接口
  3. 迭代器类至少需要重写hasNext()方法与next()方法;
  4. LinkedList重写iterator()方法。

修改后的双向链表类

import java.util.Iterator;

public class LinkedList<T> implements Iterable<T>{
    //起始节点,指向第一个节点
    private Node<T> start;
    //结束节点,指向最后一个节点
    private Node<T> tail;
    //链表长度
    private int length;

    /**
     * 添加元素(尾插)
     * @param data 需要添加进链表的元素
     */
    public void add(T data){
        tailInsert(data);
    }

    /**
     * 添加元素(尾插)
     * @param data 需要添进链表的元素序列
     */
    public void add(T... data){
        tailInsert(data);
    }

    /**
     * 获取元素
     * @param index 元素下标
     * @return 返回下标对应的元素
     */
    public T get(int index){
        //下标越界
        if (length - 1 < index){
            throw new RuntimeException("链表没有那么多元素");
        }

        int i = 0;
        Node<T> res = start;
        while (i++ != index){
            res = res.next;
        }
        return res.data;
    }

    public int size(){
        return length;
    }

    /**
     * 头插
     * @param element 需要插入的数据
     */
    public void startInsert(T element){
        //起始节点替换为新节点
        start = new Node<>(null, element, start);
        //新节点放置在起始节点之前
        if (start.next != null){
            start.next.previous = start;
        }
        //如果尾节点为空,新节点就是尾节点
        if (null == tail){
            tail = start;
        }
        length++;
    }

    /**
     * 批量头插
     * @param elements 需要头插的元素序列
     */
    @SafeVarargs
    public final void startInsert(T... elements){
        //临时链
        Node<T> tempLinkStart = null;
        Node<T> tempLinkTail = null;

        //元素添加到临时链
        for (T element : elements){
            if (null == tempLinkStart && null == tempLinkTail){
                tempLinkStart = new Node<>(null, element, null);
                tempLinkTail = tempLinkStart;
            }else{
                tempLinkStart = tempLinkStart.addPrevious(element);
            }
        }

        //临时链添加到表起始
        if (null != tempLinkTail){
            tempLinkTail.next = start;
            if (null != start){
                start.previous = tempLinkTail;
            }else{
                tail = tempLinkTail;
            }
            start = tempLinkStart;

            length += elements.length;
        }

    }

    /**
     * 尾插
     * @param element 需要插入的数据
     */
    public void tailInsert(T element){
        //替换结束节点
        tail = new Node<>(tail, element, null);
        //放在结束节点之后
        if (tail.previous != null){
            tail.previous.next = tail;
        }
        //如果起始节点为空,新节点就是起始节点
        if (null == start){
            start = tail;
        }
        length++;
    }

    /**
     * 批量尾插
     * @param elements 需要尾插的元素序列
     */
    @SafeVarargs
    public final void tailInsert(T... elements){
        //临时链
        Node<T> tempLinkStart = null;
        Node<T> tempLinkTail = null;

        //元素尾插进入临时链
        for (T element : elements){
            if (null == tempLinkStart && null == tempLinkTail){
                tempLinkStart = new Node<>(null, element, null);
                tempLinkTail = tempLinkStart;
            }else{
                tempLinkTail = tempLinkTail.addNext(element);
            }
        }

        //临时链加入链表
        if (null != tempLinkStart){
            tempLinkStart.previous = tail;
            if (null != tail){
                tail.next = tempLinkStart;
            }else{
                start = tempLinkStart;
            }
            tail = tempLinkTail;

            length += elements.length;
        }
    }

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


    /**
     * 链表节点类
     */
    static class Node<E>{
        //前驱节点
        Node<E> previous;
        //数据
        E data;
        //后继节点
        Node<E> next;

        Node() {
        }

        Node(Node<E> previous, E data, Node<E> next) {
            this.previous = previous;
            this.data = data;
            this.next = next;
        }

        /**
         * 在本节点之后插入一个元素
         * @param data 需要插入的元素E
         * @return 返回新插入的节点
         */
        Node<E> addNext(E data){
            this.next = new Node<E>(this, data, null);
            return this.next;
        }

        /**
         * 在本节点之前插入一个元素
         * @param data 需要插入的元素
         * @return 返回新插入的节点
         */
        Node<E> addPrevious(E data){
            this.previous = new Node<E>(null, data, this);
            return this.previous;
        }
    }

    /**
     * 迭代器
     * @param <T>
     */
    private class LinkedListIterator<T> implements Iterator<T>{
        Node<T> iter;

        public LinkedListIterator() {
            iter = (Node<T>) new Node<>(null,null,start);
        }

        @Override
        public boolean hasNext() {
            iter = iter.next;
            return iter != null;
        }

        @Override
        public T next() {
            return iter.data;
        }
    }
}

增强for循环遍历的结果

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值