迭代器是如何创建的?

时间:2012-06-02 15:27:00

标签: java collections iterator

创建Iterator的常用方法是:

Iterator iter = myarray.iterator(); 

有人可以告诉我如何在没有新操作员的情况下创建吗? 我知道Iterator是一个接口,所以谁实现它?

8 个答案:

答案 0 :(得分:4)

您尚未显示myarray是什么,但这是找到实施的关键。例如,如果myarray在执行时引用ArrayList,那么它将调用ArrayList.iterator(),它将返回私有ArrayList.Itr类的实例。 (至少在我碰巧看到的JRE实现中。)

答案 1 :(得分:4)

以下是该部分的ArrayList类的代码段。如您所见,有一个实现接口Iterator的内部私有类,并返回此类的实例。

  766       /**
  767        * Returns an iterator over the elements in this list in proper sequence.
  768        *
  769        * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
  770        *
  771        * @return an iterator over the elements in this list in proper sequence
  772        */
  773       public Iterator<E> iterator() {
  774           return new Itr();
  775       }
  776   
  777       /**
  778        * An optimized version of AbstractList.Itr
  779        */
  780       private class Itr implements Iterator<E> {
  781           int cursor;       // index of next element to return
  782           int lastRet = -1; // index of last element returned; -1 if no such
  783           int expectedModCount = modCount;
  784   
  785           public boolean hasNext() {
  786               return cursor != size;
  787           }
  788   
  789           @SuppressWarnings("unchecked")
  790           public E next() {
  791               checkForComodification();
  792               int i = cursor;
  793               if (i >= size)
  794                   throw new NoSuchElementException();
  795               Object[] elementData = ArrayList.this.elementData;
  796               if (i >= elementData.length)
  797                   throw new ConcurrentModificationException();
  798               cursor = i + 1;
  799               return (E) elementData[lastRet = i];
  800           }
  801   
  802           public void remove() {
  803               if (lastRet < 0)
  804                   throw new IllegalStateException();
  805               checkForComodification();
  806   
  807               try {
  808                   ArrayList.this.remove(lastRet);
  809                   cursor = lastRet;
  810                   lastRet = -1;
  811                   expectedModCount = modCount;
  812               } catch (IndexOutOfBoundsException ex) {
  813                   throw new ConcurrentModificationException();
  814               }
  815           }
  816   
  817           final void checkForComodification() {
  818               if (modCount != expectedModCount)
  819                   throw new ConcurrentModificationException();
  820           }
  821       }

答案 2 :(得分:3)

如果你查看iterator()的实现内部,那里会有一个new。例如,这是OpenJDK ArrayListiterator()方法:

public Iterator<E> iterator() {
    return new Itr();
}

反过来,Itr指的是实现Iterator接口的私有内部类:

private class Itr implements Iterator<E> {
    // implementation details
}

答案 3 :(得分:1)

myarray.iterator是一个功能。 new运算符仅适用于类型。作为Mr. Skeet stated in his answer,返回值可能是实现Iterator的内部类,而iterator()方法的实现在内部类上调用new

答案 4 :(得分:0)

迭代器通常被实现为数据结构的私有内部类,因此可以编写其方法以适当地迭代该结构的数据。所以迭代器只能通过数据结构类提供的方法访问,在你的情况下

myarray.iterator();

答案 5 :(得分:0)

首先来自myarray引用的对象类必须实现接口Iterable。这意味着该类必须向Iterator iterator()方法添加实现。

为了方便起见,iterator()方法返回实现Iterator接口的私有内部类的对象。这样做是因为内部类可以访问外部类的所有字段(甚至是私有)。

以下是反向数组迭代器

的示例
class ReverseArray implements Iterable{
    private Object[] data;// some data to iterate
    public ReverseArray(Object[] data) {
        this.data=data;
    }
    private class ReverseIterator implements Iterator {
        int counter = data.length;

        public boolean hasNext() {
            if(counter>0)
                return true;
            else
                return false;
        }

        public Object next() {
            return data[--counter];
        }

        public void remove() {
            //TODO Auto-generated method stub
        }
    }

    public Iterator<Integer> iterator() {
        return new ReverseIterator();
    }
}

让我们测试一下

    public static void main(String[] args) {
        ReverseArray reverseArray=new ReverseArray(new Integer[]{1,2,3,4,5});
        for(Object i:reverseArray)
            System.out.print(i+"; ");
        //OUT: 5; 4; 3; 2; 1;  
    }

答案 6 :(得分:0)

Iterator是一个接口,它已经实现了 List 接口的每个实现,如 ArrayList,Vector,LinkedList 以及其他你不需要担心它的实现只是使用它

答案 7 :(得分:0)

实现Iterable接口的标准库中的集合类通常具有扩展Iterator的内部类,尽管这不是必需的。您可以在任何地方对Iterator进行子类化和实例化,就像任何其他类一样。

以下是我的utils中的一个示例,其中我编写了一个为给定数组提供Iterable实例的方法。

public static Iterable<A> asIterable(final A[] xs) {
  return new Iterable<A>() {
    @Override
    public Iterator<A> iterator() {
      return new Iterator<A>() {
        private int i = 0;

        @Override
        public boolean hasNext() {
          return i < xs.length;
        }

        @Override
        public A next() {
          A x = xs[i];
          i++;
          return x;
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException(
            "Cannot remove an element from an array.");
        }
      };
    }
  };
}