我是Java的新手,所以也许对你们中的一些人来说,我的问题看起来很傻。
正如我从一些教程中理解的那样,如果我需要在我的自定义对象上创建,那么该对象必须实现Iterable接口。
我的问题是为什么我需要Iterator接口以及为什么要使用它?
答案 0 :(得分: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 :(得分:1)
Iterator是设计模式,它允许以某种方式经历相同对象的集合,这也允许隐藏存储元素的实现和用户的迭代机制。正如您在javadoc中看到的,许多类实现了Itarable
接口,而不仅仅是集合。在示例中,它允许您以相同的性能迭代两个List
实现,当ArrayList
同时给出索引但是LinkedList
为了给某些索引需要将之前的所有元素都转到此数字并且这慢得多。但是当你从这个实现中得到Iterator
时,你会在两种情况下获得相同的性能,因为迭代算法在两个列表中都以不同的方式进行了优化。 ResultSet
也是迭代器,但它不实现java.util
的接口,它允许以相同的方式迭代db中的所有查询结果,并隐藏负责元素存储和数据库参与的结构。在示例中,当您需要进行一些优化时,您可以在每次下一次结果调用时创建新的ResultSet实现查询数据库或者您想要的任何内容,因为它还会将客户端代码与元素存储实现和迭代算法分离。