【问题标题】:Custom iterator for linkedlist链表的自定义迭代器
【发布时间】:2017-07-25 05:30:18
【问题描述】:

我创建了一个自定义链表。我也为它做了一个迭代器。但据我了解,程序不会在方法 size() 中进入循环。它出什么问题了?是关于我不正确的循环还是iterator()。每个节点都有字段:nextIndexprevIndexvalue

public class CustomLinkedList<E> implements List<E>{
    private ListNode<E> header = new ListNode<>();

    public CustomLinkedList() {
        this.header = new ListNode();
    }

    @Override
    public int size() {
        int size = 0;
        for(E it : this) {
            size++;
        }
        return size;
    }

    @Override
    public boolean isEmpty() {
        if(this.header == null){
            return true;
        } else {return false;}
    }

    @Override
    public boolean contains(Object o) {
        if(((Integer) header.getValue() == 42) && ((Integer) header.getNextIndex().getValue() == 38)) return true;
        return false;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            private ListNode it = header;

            @Override
            public boolean hasNext() {
                return (it.getNextIndex() != header) && (it.getNextIndex() != null);
            }

            @Override
            public E next() {
                it = it.getNextIndex();
                return (E) it.getValue();
            }

            @Override
            public void remove()
            {
                throw new UnsupportedOperationException("Iterator is read-only");
            }
        };
    }


    @Override
    public boolean add(E e) {
        ListNode<E> temp = new ListNode<>();
        temp.setValue(e);
        if (this.size() < 1) {
            header.setValue(e);
            header.setPrevIndex(header);
            header.setNextIndex(header);
        } else {
            temp.setNextIndex(header);
            ListNode tempLast = header.getPrevIndex();
            tempLast.setNextIndex(temp);
            header.setPrevIndex(temp);
            temp.setPrevIndex(tempLast);
        }
        return true;
    }

    @Override
    public boolean remove(Object o) {
        return true;
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        throw new NotImplementedException();
    }

    @Override
    public void clear() {
        throw new NotImplementedException();
    }

    @Override
    public E get(int index) {
        throw new NotImplementedException();
    }

    @Override
    public int indexOf(Object o) {
        throw new NotImplementedException();
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        throw new NotImplementedException();
    }
}

【问题讨论】:

    标签: java for-loop iterator


    【解决方案1】:

    您从header.getNextIndex() == null 开始,然后调用add(E e) 一次。 在add()size() 内部将返回 0,因此您可以设置 header.setPrevIndex(header)header.setNextIndex(header)

    接下来你再次调用add(E e). Insideadd(),size()will callhasNext()andhasNext()will check (it.getNextIndex() != header) &amp;&amp; (it.getNextIndex() != null) 将返回 false 因为@ 987654333@ 因此 size() 将始终小于一

    您的代码中还有很多其他错误。更好的部分实现类似于

    public class CustomLinkedList<E> implements List<E> {
    
        private ListNode<E> header;
    
        public CustomLinkedList() {
            this.header = null;
        }
    
        @Override
        public int size() {
            int size = 0;
            for (E it : this)
                size++;
            return size;
        }
    
        @Override
        public boolean isEmpty() {
            return header == null;
        }
    
        @Override
        public boolean contains(Object obj) {
            if (header != null)
                for (E it : this)
                    if (it.equals(obj))
                        return true;
            return false;
        }
    
        @Override
        public Iterator<E> iterator() {
            return new Iterator<E>() {
                private ListNode<E> it = null;
    
                @Override
                public boolean hasNext() {
                    if (it==null && header!=null)
                        return true;
                    else if (it != null)
                        return it.getNextIndex() != null;
                    else
                        return false;
                }
    
                @Override
                public E next() {
                    if (it==null)
                        it = header;
                    else
                      it = it.getNextIndex(); 
                    return it.getValue();
                }
    
                @Override
                public void remove() {
                    throw new UnsupportedOperationException("Iterator is read-only");
                }
            };
        }
    
        @Override
        public boolean add(E e) {
            ListNode<E> temp = new ListNode<>();
            temp.setValue(e);
            if (header == null) {
                header = temp;
            } else {
                ListNode<E> it = header;
                while (it.getNextIndex() != null)
                    it = it.getNextIndex();
                temp.setPrevIndex(it);
                it.setNextIndex(temp);
            }
            return true;
        }
    
    }
    

    【讨论】:

    • 如何在for的第一次迭代中改进它以获取header.value?现在没有了。因为在第一次迭代中我们得到了 header.getNextIndex().getValue().
    • 是的,你是对的。我已经编辑了 hasNext() 中的代码和它的初始化,但没有测试它。我觉得现在可以了。
    【解决方案2】:

    您需要使用iteratorhasNextnext 方法循环遍历元素并增加大小,例如:

    @Override
    public int size() {
        int size = 0;
        for(Iterator<String> it = this.iterator(); it.hasNext(); it.next()){
            size++;
        }
        return size;
    }
    

    【讨论】:

    • 仍然没有进入循环。所以问题要么是不正确的添加,要么是 hasNext()。对吗?
    • 如果它没有进入循环,那么你的列表很可能是空的。
    • 它不会进入循环,因为add() 方法是错误的。在另一个答案中阅读我的解释。
    猜你喜欢
    • 2021-02-27
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 2016-07-10
    • 2021-06-19
    • 2013-02-17
    • 2015-02-04
    相关资源
    最近更新 更多