覆盖循环数组中的迭代器

时间:2016-05-21 00:17:40

标签: java arrays iterator deque circular-list

我正在编写自己的Deque类,我需要覆盖迭代器。

示例:假设数组是[3,4,5,null,null,null,1,2],其中1是前面,5是结束。我需要能够使用迭代器从1开始并在5之后结束。

这是我的整个Deque课程。我相信除了hasNext方法之外,迭代器中的一切都是正确的。

import java.util.Iterator;
import java.util.*;
import javax.swing.border.*;

public class Deque20<E> implements Iterable<E> {

    public final int INITIAL_SIZE = 16;

    private E[] items;
    private E[] temp;
    private int size;
    private int first;

    @SuppressWarnings("unchecked")  // Casting Object[] to E[]
    public Deque20() {
        items = (E[]) new Object[INITIAL_SIZE];
        size = 0;
        first = 0;
    }

    public void addFirst(E e){
        if(size == items.length){
            doubleSize();
        }
        first -= 1;
        if(first == -1){
            first = items.length - 1;
        }
        items[first] = e;
        size += 1;
    }

    public void addLast(E e){
        if(size == items.length){
            doubleSize();
        }
        items[(first + size) % items.length] = e;
        size++; 
    }

    public void removeFirst(){
        items[first] = null;
        first++;
        size--;
    }

    public void removeLast(){
        items[((first + size) % items.length) - 1] = null;
        size--;
    }

    public E peekFirst(){
        if(size == 1){
            return items[first];
        }else{
            return items[first];
        }
    }

    public E peekLast(){
        if(size == 1){
            return items[first];
        }else{
            return items[((first + size) % items.length) - 1];
        }
    }

    @SuppressWarnings("unchecked")
    private void doubleSize(){
        temp = (E[]) new Object[size * 2];
        for(int i = 0; i < size; i++){
            temp[i] = items[(first + i) % items.length];
        }
        items = temp;
        first = 0;
    }

    @SuppressWarnings("unchecked")
    private void realign(){
        temp = (E[]) new Object[size];
        for(int i = 0; i < size; i++){
            temp[i] = items[(first + i) % items.length];
        }
        items = temp;
        first = 0;
    }

    public int size(){
        return size;
    }

    public boolean isEmpty(){
        if(size == 0){
            return true;
        }
        return false;
    }

    @Override
    public Iterator<E> iterator() {
        Iterator<E> it = new Iterator<E>(){
            private int currentIndex = first;

            @Override
            public boolean hasNext() {
                return currentIndex < size && items[currentIndex] != null;
            }

            @Override
            public E next() {
                return items[currentIndex++];
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
        return it;
    }

    public String toString(){
        String str = "[";
        for(E e : items){
            str += e + ",";
        }
        str += "]";
        return str;
    }
}

编辑:我的问题是如何为我的Iterator修复hasNext方法。当迭代时,它只会到达列表的末尾而不是绕到前面。

Deque20类只是赋值我必须编写自己的类,其行为类似于内置的ArrayDeque。

2 个答案:

答案 0 :(得分:1)

您可能需要在迭代器内部类的构造函数中初始化currentIndex,并在超出大小时将currentIndex设置为0(假设hasNext将始终在next之前调用,否则下一个应该具有相同的。),如:

        public Iterator() {
            // init first position - assuming first element is always available somewhere in the array.
            for (int i = 0;i<items.length;i++) {
                if (items[i] == first) {
                    currentIndex = i;
                    break;
                }
            }
        }
    @Override
    public boolean hasNext() {
        if (currentIndex >= size()) {
            currentIndex = 0;
        }
        return  items[currentIndex] != null;
    }

如果没有hasNext()的next()调用:

 public E next() {
            if (currentIndex >= size()) {
                currentIndex = 0;
            }
            return items[currentIndex++];
        }

答案 1 :(得分:0)

我使用currentOffset中的first

@Override
public Iterator<E> iterator() {
    return new Iterator<E>() {
        private int currentOffset = 0;

        @Override
        public boolean hasNext() {
            return currentOffset < size;
        }

        @Override
        public E next() {
            E n = items[(first + currentOffset) % items.length];
            currentOffset += 1;
            return n;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    };
}

另外,我建议您将方法doubleSize()重命名为doubleCapacity(),因为实际上是在不改变双端队列大小的情况下将容量加倍。理想情况下,您应该考虑处理SimultaneousModificationException,其中您在迭代时检测到双端队列的更改。