如果想用foreach遍歷自定義類的集合,自定義類通常需要實現implement iterable接口. 該接口定義了Iterator<T> iterator()方法. 有些時候這個iterator方法可以供用類里面的集合屬性.iterator()返回.
示例:
public class Teacher implements Iterable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Iterator iterator() {
return new Itr();
}
public static void main(String[] args) {
Teacher t = new Teacher();
t.setName("aaaaaaa");
t.setAge(23);
for (Object o : t) {
System.out.println(o.toString());
}
}
private class Itr implements Iterator{
private int cursor=0; // 屬性的索引
private Field[] fields = Teacher.class.getDeclaredFields(); // 屬性的數組
public boolean hasNext() {
return cursor!=(Teacher.class.getDeclaredFields().length);
}
public Object next() {
Object o=null;
try{
fields[cursor].setAccessible(true); // 讓內部類可以訪問外部類的私有屬性的值
o = fields[cursor].getName()+" "+fields[cursor].get(Teacher.this);
cursor++;
}catch(Exception e){
System.out.println(e);
}
return o;
}
public void remove() {
// TODO Auto-generated method stub
}
}
}
示例2:
import java.util.Iterator;
//測試類
public class Exec {
public static void main(String[] args) throws Exception {
// 創建學生集合類
Students students = new Students(10);
// 通過for each語句迭代循環學生集合類的每個元素
for (Object obj : students) {
Student stu = (Student) obj;
System.out.println(stu.getSid() + ":" + stu.getName());
}
}
}
// 支持for each迭代循環的學生集合類
class Students implements Iterable {
// 存儲所有學生類的數組
private Student[] stus;
// 該構造函數可以生成指定大小的學生類變量數組,并初始化該學生類變量數組
public Students(int size) {
stus = new Student[size];
for (int i = 0; i < size; i++) {
stus[i] = new Student(String.valueOf(i), "學生" + String.valueOf(i));
}
}
// 實現Iterable接口的重要方法,返回自定義的迭代類變量
public Iterator iterator() {
return new StudentIterator();
}
// 實現Iterator接口的私有內部類,外界無法直接訪問
private class StudentIterator implements Iterator {
// 當前迭代元素的下標
private int index = 0;
// 判斷是否還有下一個元素,如果迭代到最后一個元素就返回false
public boolean hasNext() {
return index != stus.length;
}
// 返回當前元素數據,并遞增下標
public Object next() {
return stus[index++];
}
// 這里不支持,拋出不支持操作異常
public void remove() {
throw new UnsupportedOperationException();
}
}
}
// 學生類
class Student {
// 學生學號
private String sid;
// 學生姓名
private String name;
// 默認構造函數
public Student() {
}
// 支持屬性值初始化的構造函數
public Student(String sid, String name) {
setSid(sid);
setName(name);
}
// 學生學號的讀取函數
public String getSid() {
return sid;
}
// 學生學號的設置函數
public void setSid(String sid) {
this.sid = sid;
}
// 學生姓名的讀取函數
public String getName() {
return name;
}
// 學生姓名的設置函數
public void setName(String name) {
this.name = name;
}
// 格式化字符信息輸出
public String toString() {
return this.sid + ":" + this.name;
}
}
----------------------------------------------------------------------------
看一下JDK中的集合類,比如List一族或者Set一族,
都是實現了Iterable接口,但并不直接實現Iterator接口。
仔細想一下這么做是有道理的。因為Iterator接口的核心方法next()或者hasNext()
是依賴于迭代器的當前迭代位置的。
如果Collection直接實現Iterator接口,勢必導致集合對象中包含當前迭代位置的數據(指針)。
當集合在不同方法間被傳遞時,由于當前迭代位置不可預置,那么next()方法的結果會變成不可預知。
除非再為Iterator接口添加一個reset()方法,用來重置當前迭代位置。
但即時這樣,Collection也只能同時存在一個當前迭代位置。
而Iterable則不然,每次調用都會返回一個從頭開始計數的迭代器。
多個迭代器是互不干擾的。