Iterator 接口在 java.util 包中。实现了 Iterator 接口的类就可以支持遍历操作。
public interface Iterator<E> {
// 只需要关注到这两个抽象方法
boolean hasNext(); // 还有没有下一个元素
E next(); // 返回下一个元素
}
Iterable 接口在 java.lang 包中。实现了 Iterable 接口的类就可以支持 forEach 循环。
import java.util.Iterator;
public interface Iterable<T> {
// 只需要关注这个抽象方法
Iterator<T> iterator(); // 得到一个迭代器
}
不实现 Iterable 接口时:
// 不实现 Iterable 接口
// 容器类
public class MyElementList {
private Object[] elements;
private int curr;
// @Override
// public Iterator iterator() {
// return new Iterator() { // 由于 Iterator 是接口,不能直接 new 实例,所以用一个匿名类来实现实例的创建
//
// int pointer = 0;
//
// @Override
// public boolean hasNext() {
// return pointer < size();
// }
//
// @Override
// public Object next() {
// return elements[pointer++];
// }
// };
// }
public int size() {
return curr;
}
public MyElementList() {
elements = new Object[16];
curr = 0;
}
public void add(Object o) {
if (curr < elements.length - 1) {
elements[curr] = o;
curr++;
} else {
System.out.println("Out of bound.");
}
}
}
// 调用类
public class TestUse {
public static void main(String[] args) {
MyElementList list = new MyElementList();
System.out.println(list.size()); // 0
list.add("abc");
list.add(123);
System.out.println(list.size()); // 2
for (Object o : list){
System.out.println(o);
}
/* 报错
java: for-each 不适用于表达式类型
要求: 数组或 java.lang.Iterable
找到: iter.MyElementList
*/
/*
若 MyElementList 里的 elements 是 public 的,倒是可以:
for (Object o : list.elements){
System.out.println(o);
}
但现在 elements 也是 private 的。
*/
}
}
// 可见是不支持 forEach 循环
实现 Iterable 接口时:
// 实现 Iterable 接口
// 容器类
import java.util.Iterator;
public class MyElementList implements Iterable {
private Object[] elements;
private int curr;
@Override
public Iterator iterator() {
return new Iterator() { // 由于 Iterator 是接口,不能直接 new 实例,所以用一个匿名类来实现实例的创建
int pointer = 0;
@Override
public boolean hasNext() {
return pointer < size();
}
@Override
public Object next() {
return elements[pointer++];
}
};
}
public int size() {
return curr;
}
public MyElementList() {
elements = new Object[16];
curr = 0;
}
public void add(Object o) {
if (curr < elements.length - 1) {
elements[curr] = o;
curr++;
} else {
System.out.println("Out of bound.");
}
}
}
// 调用类
public class TestUse {
public static void main(String[] args) {
MyElementList list = new MyElementList();
System.out.println(list.size()); // 0
list.add("abc");
list.add(123);
System.out.println(list.size()); // 2
for (Object o : list){
System.out.println(o);
}
}
}
// 输出结果:
/*
0
2
abc
123
Process finished with exit code 0
*/
// 可见,实现了 Iterable 接口之后,就支持 forEach 循环了。
注意:是实现了 Iterable 接口的类,支持 forEach,而并非是实现了 Iterator 接口的类支持 forEach。
// 实现的若是 Iterator 接口而非 Iterable 接口
// 容器类
import java.util.Iterator;
public class MyElementList implements Iterator {
private Object[] elements;
private int curr;
// @Override
// public Iterator iterator() {
// return new Iterator() { // 由于 Iterator 是接口,不能直接 new 实例,所以用一个匿名类来实现实例的创建
//
// int pointer = 0;
//
// @Override
// public boolean hasNext() {
// return pointer < size();
// }
//
// @Override
// public T next() {
// return (T)elements[pointer++];
// }
// };
// }
public int size() {
return curr;
}
public MyElementList() {
elements = new Object[16];
curr = 0;
}
public void add(Object o) {
if (curr < elements.length - 1) {
elements[curr] = o;
curr++;
} else {
System.out.println("Out of bound.");
}
}
// 使用类似的代码
int pointer = 0;
@Override
public boolean hasNext() {
return pointer < size();
}
@Override
public Object next() {
return elements[pointer++];
}
}
// 调用类
public class TestUse {
public static void main(String[] args) {
MyElementList list = new MyElementList();
System.out.println(list.size()); // 0
list.add("abc");
list.add(123);
System.out.println(list.size()); // 2
System.out.println(list.next()); // abc
System.out.println(list.next()); // 123
System.out.println(list.next()); // null
for (Object o : list){
System.out.println(o);
}
/* 报错
java: for-each 不适用于表达式类型
要求: 数组或 java.lang.Iterable
找到: iter.MyElementList
*/
// 这也不是因为之前执行过多次 .next(),把上面的 .next() 语句全部注释,还是同样的报错
}
}
// 可见,实现 Iterator 接口,并不能让类支持 forEach 循环。
这其实很好理解,实现 Iterator 并不会获得一个生成器(而是自己变成了一个生成器),而实现 Iteralbe 会获得一个生成器。
那么是否可以不实现 Iterable,而直接通过导入 Iterator 类然后 new 一个 Iterator 实例返回一个生成器来实现支持 forEach 呢?
其实只需要保留一开始的代码,然后把 implents Iterable
去掉测试一下即可。
import java.util.Iterator;
public class MyElementList {
private Object[] elements;
private int curr;
// @Override
public Iterator iterator() {
return new Iterator() { // 由于 Iterator 是接口,不能直接 new 实例,所以用一个匿名类来实现实例的创建
int pointer = 0;
@Override
public boolean hasNext() {
return pointer < size();
}
@Override
public Object next() {
return elements[pointer++];
}
};
}
public int size() {
return curr;
}
public MyElementList() {
elements = new Object[16];
curr = 0;
}
public void add(Object o) {
if (curr < elements.length - 1) {
elements[curr] = o;
curr++;
} else {
System.out.println("Out of bound.");
}
}
}
// 调用类
public class TestUse {
public static void main(String[] args) {
MyElementList list = new MyElementList();
System.out.println(list.size()); // 0
list.add("abc");
list.add(123);
System.out.println(list.size()); // 2
for (Object o : list){
System.out.println(o);
}
/*
报错:
java: for-each 不适用于表达式类型
要求: 数组或 java.lang.Iterable 找到: iter.MyElementList
*/ }
}
// 可见,还是不行,因此就是要实现 Iterable 接口,才能让该类支持 forEach 循环。