2017-07-01 106 views
-1

我是Java新手,所以也许对你们中的一些人来说,我的问题似乎很愚蠢。为什么我需要Iterator接口,为什么要使用它?

正如我从一些教程了解,如果我需要在我的自定义对象foreach上做对象必须实现Iterable接口。

我的问题是为什么我需要Iterator接口,为什么我应该使用它?

回答

3

正如您所提到的,Iterable用于foreach循环。

并非所有东西都可以在foreach循环中使用,对吧?你认为这会做什么?

for (int a : 10) 

的Java的设计者希望使编译器能够发现这么多废话,它作为一个编译器错误向您汇报。所以他们认为,“在foreach循环中可以使用什么样的东西?” “好吧”,他们认为,“对象必须能够返回迭代器”。该接口的诞生:

public interface Iterable<T> { 
    /** 
    * Returns an iterator over elements of type {@code T}. 
    * 
    * @return an Iterator. 
    */ 
    Iterator<T> iterator(); 
} 

编译器可以查一下foreach循环的对象是否实现Iterable与否。如果没有,请吐出一个错误。你可以认为这是编译器的一种“标记”,它说“是的,我可以迭代!”

“什么是迭代器呢?”他们再次想到:“好吧,迭代器应该能够返回下一个元素并返回它是否有下一个元素,一些迭代器也应该能够移除元素” 。所以这个接口的诞生:

public interface Iterator<E> { 
    /** 
    * Returns {@code true} if the iteration has more elements. 
    * (In other words, returns {@code true} if {@link #next} would 
    * return an element rather than throwing an exception.) 
    * 
    * @return {@code true} if the iteration has more elements 
    */ 
    boolean hasNext(); 

    /** 
    * Returns the next element in the iteration. 
    * 
    * @return the next element in the iteration 
    * @throws NoSuchElementException if the iteration has no more elements 
    */ 
    E next(); 

    /** 
    * Removes from the underlying collection the last element returned 
    * by this iterator (optional operation). This method can be called 
    * only once per call to {@link #next}. The behavior of an iterator 
    * is unspecified if the underlying collection is modified while the 
    * iteration is in progress in any way other than by calling this 
    * method. 
    * 
    * @implSpec 
    * The default implementation throws an instance of 
    * {@link UnsupportedOperationException} and performs no other action. 
    * 
    * @throws UnsupportedOperationException if the {@code remove} 
    *   operation is not supported by this iterator 
    * 
    * @throws IllegalStateException if the {@code next} method has not 
    *   yet been called, or the {@code remove} method has already 
    *   been called after the last call to the {@code next} 
    *   method 
    */ 
    default void remove() { 
     throw new UnsupportedOperationException("remove"); 
    } 
} 
1

Iterator是设计模式,它允许要经过一定的方式同一个对象的集合,这也让隐藏实现存储元素,并从用户的迭代机制。正如你可以在javadoc中看到的很多类实现接口,不仅仅是集合。在示例中,它允许您在相同性能中迭代两个List实现,当ArrayList在同一时间给出索引时,但是LinkedList给定某个索引需要先前将所有元素都转换为该数字,并且这会慢得多。但是当你从这个实现中获得Iterator时,你会在两种情况下获得相同的性能,因为迭代算法在这两个列表中以不同的方式进行了优化。 ResultSet也是迭代器,但它没有实现从java.util的接口,它允许以相同的方式在db中查询所有结果的迭代,并隐藏返回元素store和db参与的负责结构。在例子中,当你需要一些优化时,你可以为每个下一个结果调用或任何你想要的新ResultSet实现查询db,因为它也将客户端代码从元素存储实现和迭代算法中分离出来。