3

创建一个常见的方法Iterator是:

Iterator iter = myarray.iterator(); 

谁能告诉我在没有 new 运算符的情况下如何创建 iter ?我知道Iterator是一个接口,那么谁来实现它呢?

4

8 回答 8

4

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

于 2012-06-02T15:29:26.277 回答
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       }
于 2012-06-02T15:30:31.643 回答
3

如果您查看 的实现内部iterator(),就会在new某个地方有一个内部。例如,这是iterator()来自 OpenJDK 的方法ArrayList

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

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

private class Itr implements Iterator<E> {
    // implementation details
}
于 2012-06-02T15:29:19.130 回答
1

myarray.iterator是一个函数。new运算符仅适用于类型。正如斯基特先生在他的回答中所说,返回值很可能是一个实现的内部类,Iterator并且该iterator()方法的实现调用new了内部类。

于 2012-06-02T15:33:18.303 回答
0

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

myarray.iterator();
于 2012-06-02T15:35:05.290 回答
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;  
    }
于 2012-06-02T16:07:32.047 回答
0

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

于 2012-06-02T16:52:41.513 回答
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.");
        }
      };
    }
  };
}
于 2012-06-02T19:42:38.710 回答