需要帮助理解迭代器实现

时间:2014-03-08 06:42:50

标签: java iterator

我无法理解我在课堂上给出的作业,描述如下:

创建三个公共队列类calles QueueExtendingVect和QueueContaingVect。第一个应该通过扩展它来实现使用Vector类的队列,并实现Iterator类型的迭代器;第二个应该使用Vector类实现一个队列,包含一个Vector对象,当然还要实现Iterator类型的迭代器。每个类都应该实现iterator()实例方法来创建Iterator实例。通过在调用时抛出java.lang.UnsupportedOperationException,在Iterator中实现remove()。请注意,Iterator.next()返回对存储的实际客户端对象的引用,并使迭代器前进。

通过扩展向量,我可以创建一个Iterator实例并使用它迭代向量,并使用.next()和remove()方法。

这是我到目前为止的代码......

import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Vector;

@SuppressWarnings("rawtypes")
public class QueueExtendingVector extends Vector  implements Cloneable, Iterable{

/** no-args constructor*/       
    public QueueExtendingVector() { 

    }   

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


/** adds element to end of Queue takes Object as arguement, calls addElement()*/    
    public void enqueue (Object c){
        this.addElement(c); 
    }   
/** dequeue() removes first element of the Queue
 * @return */   
    public Object dequeue(){

    if (this.size() !=0){
        Object deleted =  this.elementAt(0);
            this.removeElementAt(0);
            return deleted;
        }
    else{
    return -1;
    }

    }
/** empty() returns true if Queue is empty*/    
    public boolean empty(){
        return this.isEmpty();  
    }   
/** makeNull sets all elements of Queue to null*/
    public void makeNull(){

        int s = this.size();   // number of elements not capacity
        //System.out.println(s);
        for ( int i = 0 ; i < s ; i++){
            this.set(i, null);
        }       
    }

/** equals() checks quality of two QEV object references, returns true if  references point to same object and true if objects referred to are equal*/
    public boolean equals(Object o ){   

        if( this == o ){  // if pointing at same object return true
            return true;
        }
        if(!(o instanceof QueueExtendingVector)){ // if o not an instance of QEV return false
            return false;
        }

        int mySize = this.size(); // size of this QEV
        int compareToSize = ((QueueExtendingVector)o).size(); // size of object comparing to

        if(mySize != compareToSize){ // if the sizes (number of elements) are not same returns false;
            System.out.println("Sizes Unequal");
            return false;
        }               
        for ( int i = 0 ; i < mySize; i++ ) // loop through QEV
            if(  ((QueueExtendingVector)o).elementAt(i).equals(this.elementAt(i))){ // if equal (true) continue looping         
            }
            else { // if not equal, break from loop return false
                return false;               
        }   
        return true; // after loop finishes returns true
}
/** toString() method returns String*/
    public String toString(){       

        String s = "";

        for ( int i = 0 ; i < this.size(); i++){
            s+= this.elementAt(i).toString() + " , ";           
        }
        return s;
    }
/** front() returns first element of Queue*/    
    public Object front(){ 
        return this.firstElement();
    }

    public Object clone(){
        Object o = null;
        Object q = new QueueExtendingVector();  

        for(int i = 0 ; i < this.size(); i++){          

            try {               
                o =  this.get(i).getClass().getMethod("clone", null).invoke(this.get(i), null);
                ((QueueExtendingVector)q).add(o);               
            } 
        //  catch (Throwable e){
            //}
            catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                System.out.println("element at index " + i + ": [" + this.get(i).getClass() + "]is not cloneable, shallow copy only preformed");
                 Object t = this.elementAt(i);               
                ((QueueExtendingVector)q).add(t); // was add o
                //throw new Error(this.elementAt(i).getClass() + " must implement Cloneable");
                //e.printStackTrace();
            } catch (NoSuchMethodException e) {
                //e.printStackTrace();
            } catch (SecurityException e) {
                //e.printStackTrace();
            }                                   
        }
        return q;

    }

in a class called A1, which we were given, and to use exactly as was such.

import java.util.Date;
import java.util.Iterator;
import java.util.Vector;


public class A1 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        QueueExtendingVector qev1 = new QueueExtendingVector();
        QueueExtendingVector qev2 = new QueueExtendingVector();
        QueueExtendingVector qev3;


        QueueContainingVector qcv1 = new QueueContainingVector();
        QueueContainingVector qcv2 = new QueueContainingVector();
        QueueContainingVector qcv3;

        CInteger ci = new CInteger(88);

        qev1.enqueue(ci);
        qev2.enqueue(ci);
        qcv1.enqueue(ci);
        qcv2.enqueue(ci);

        for ( int i = 0 ; i < 5; i++)
            if ( i%2 == 0){
                qev1.enqueue(new CInteger(i+1));
                qev2.enqueue(new CInteger(i+1));
                qcv1.enqueue(new CInteger(i+1));
                qcv2.enqueue(new CInteger(i+1));
            }
            else{
                qev1.enqueue(new Date(i*i));
                qev2.enqueue(new Date(i*i));
                qcv1.enqueue(new Date(i*i));
                qcv2.enqueue(new Date(i*i));

            }


// QueueExtendingVector ******************************************************************************************************


    if (qev1.equals(qev2)){     
        System.out.println("qev1.equals(qev2) is true");
    }
    else{
        System.out.println("qev1.equals(qev2) is false");
        }

    System.out.println("but........");
    if (qev1 == qev2){
    System.out.println("qev1 == qev2");
        }
    else{
    System.out.println("qev != qev2");
        }

    if(qev1.empty()){
        System.out.println("qev1 empty");
        }
    else{
        System.out.println("qev1 not empty");
        }

    qev3 = (QueueExtendingVector)qev1.clone();

    ci.seti(44);

    System.out.println("first element of qev1 is " + qev1.front());

    System.out.println("qev3 stringified(hopefully didn't change) = " + qev3);

    System.out.println("First elt of qev1 is: " + qev1.front());

    System.out.println(qev1.size());



    // ********** that first Iteratorstuff goes here!


    try{
    qev1.iterator().remove();

        }
    catch (UnsupportedOperationException e){
    System.out.println("Calling Iterator.remove() and throwing Exception");
        }

    Iterator i = qev1.iterator();
    for ( int j = 0 ; i.hasNext(); j ++){

    System.out.println("qev1[" + j + "] = " + i.next());
        }


    }

    }





}

我不明白的是:

try{
    qev1.iterator().remove();

        }
catch (UnsupportedOperationException e){
        System.out.println("Calling Iterator.remove() and throwing Exception");
        }

i get the illegal state exception which is thrown when , .next() is not called before .remove() is called

我不明白qev1.iterator()。remove()是如何工作的? 我需要覆盖迭代器方法吗?

oracle docs声明: IllegalStateException - 如果尚未调用下一个方法,或者在上次调用下一个方法后已经调用了remove方法

2 个答案:

答案 0 :(得分:0)

在调用next()方法之前,必须调用remove()方法来更新最后返回元素的索引,如下所示。

查看源代码&amp;评论AbstractList

private class Itr implements Iterator<E> {
    /**
     * Index of element to be returned by subsequent call to next.
     */
    int cursor = 0;

    /**
     * Index of element returned by most recent call to next or
     * previous.  Reset to -1 if this element is deleted by a call
     * to remove.
     */
    int lastRet = -1;

    public E next() {
        ...
        int i = cursor;
        E next = get(i);
        lastRet = i;
        cursor = i + 1;               
        ...
    }

    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        ...
    }

}

答案 1 :(得分:0)

Each of the classes should implement the iterator() instance method to create an Iterator instance

这是你的问题。是的,你必须覆盖iterator方法的默认实现,并通过它的声音创建自己的迭代器类。