public interface Walkable {
void walk();
}
class Animal implements Walkable{
public void walk() {
//defines some way to walk
}
}
在上面的示例中,动物类说我可以走路,并且它定义了走路的方式。
类似地,为什么不能对对象进行任何扩展却仅实现Iterator接口并暗示它是可迭代的。
class Employee{
Iterator getEmployeeIterator(){
return new EmployeeCollection();
}
}
class EmployeeCollection implements Iterator{
Employee []emp;
public boolean hasNext() {
//implementation
}
public Object next() {
//implementation
}
简单返回Iterator的Iterable接口有什么需要。它也不需要任何麻烦。如果需要任何argumnet,我可以假定它可以像提供不同类型的Iterators的工厂一样工作]
“提供通用接口”是Iterable的唯一目的吗?
我可以想到评论中也指出了一个原因。首先,如果实现Iterable
并覆盖forEach()
方法,则可以迭代如下数据结构:
for(int i : myDataStructure) {
System.out.println(i);
}
如果正确实施,它将打印数据结构中的所有元素。对于每个循环,从不同的数据结构具有不同的迭代方式的意义上说,比常规的for循环更容易。例如,对于LinkedList
,如果使用for循环进行迭代,则将花费更长的时间,因为您总是从头开始,并且每次都转到该索引处的节点。使用for-each循环,可以节省空间和时间,具体取决于数据结构。
为什么不能对对象进行任何扩展,仅实现Iterator接口并暗示它是可迭代的
迭代器具有状态。它必须知道迭代器已经返回了哪些项目,哪些没有,以及接下来将返回哪些项目。
如果集合本身是迭代器,并且增强的for循环可在迭代器上使用,您将无法像这样对它进行两次迭代:
for (Employee employee: employeeCollection) {
// do something
}
for (Employee employee: employeeCollection) {
// do something else
}
当第一个循环完成时,这意味着您已经到达迭代的结尾。因此,第二个循环不能再迭代任何项目。
您可能会争辩说,循环的开始可能以某种方式隐式地将迭代器“重置”回开始。无法重置迭代器,但是无论如何也无法解决问题。嵌套的迭代将如何工作,假设您要寻找一对生日相同的员工?
for (Employee employee1: employeeCollection) {
for (Employee employee2: employeeCollection) {
// do something
}
}
如果内部for循环和外部for循环共享迭代器状态,则此算法无法产生所有对雇员。
您确实需要一种创建fresh迭代器的方法,该方法独立于可能存在的其他迭代器。这就是Iterable
界面为您提供的。