【问题标题】:need help undestanding iterator implementation需要帮助了解迭代器实现
【发布时间】:2014-03-08 06:42:49
【问题描述】:

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

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

通过扩展vector,我可以创建一个Iterator实例并使用它来遍历vector,并使用.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 文档指出: IllegalStateException - 如果下一个方法还没有被调用,或者在最后一次调用下一个方法之后已经调用了 remove 方法

【问题讨论】:

    标签: java iterator


    【解决方案1】:
    Each of the classes should implement the iterator() instance method to create an Iterator instance
    

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

    【讨论】:

    • 好的,这就是我的想法,让我更加困惑的是当我问我的教授时,他说我只需要覆盖删除方法,而不是下一个,或者没有ext.......所以听起来我需要编写一个内部迭代器类,并覆盖方法
    【解决方案2】:

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

    看AbstractList的源码&cmets

    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();
            ...
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      • 2017-06-19
      • 2016-05-03
      • 1970-01-01
      相关资源
      最近更新 更多