Iterator、Iterable接口的使用

为什么一定要去实现Iterable这个接口呢? 为什么不直接实现Iterator接口呢?
看一下JDK中的集合类,比如List一族或者Set一族,
都是继承了Iterable接口,但并不直接继承Iterator接口。
仔细想一下这么做是有道理的。因为Iterator接口的核心方法next()或者hasNext()
是依赖于迭代器的当前迭代位置的。
如果Collection直接继承Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。
当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。
除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。
但即时这样,Collection也只能同时存在一个当前迭代位置。
而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。
多个迭代器是互不干扰的。

Student.class

public class Student {

    private String id;
    private String name;

    public Student() {
        super();
    }
    public Student(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + "]";
    }

}

StuSet.class

public class StuSet implements Iterable<Student> {

    //存储Student对象的数组
    private Student[] students = new Student[10];
    //记录数组存储的最后一个Student对象的索引+1,也就是数组存储的Student对象的个数
    private int indexes = 0;

    public StuSet(){}

    //添加Student对象
    public void add(Student stu){
        //如果students数组存储的对象已经达到上限
        if(indexes==students.length){
            int length = students.length * 2;
            Student[] stus = new Student[length];
            //把students数组存储的所有对象拷贝到拥有它2倍索引的stus数组中去
            System.arraycopy(students, 0, stus, 0, this.students.length);
            students = stus;
            students[indexes] = stu;
        } else {
            students[indexes] = stu;
        }
        indexes++;  
    }

    //返回目前存了多少个Student对象
    public int size(){
        return indexes;
    }

    //返回Students数组总长度
    public int totalSize(){
        return students.length;
    }

    @Override
    public Iterator<Student> iterator() {
        return new StudentIterator();
    }

    //实现Iterator接口的私有内部类,外界无法直接访问
    private class StudentIterator implements Iterator<Student>{

        //当前迭代元素的下标
        private int index = 0;

        // 判断是否还有下一个元素,如果迭代到最后一个元素就返回false
        @Override
        public boolean hasNext() {
            return index != indexes;
        }

        @Override
        public Student next() {
            return students[index++];
        }

        // 这里不支持,抛出不支持操作异常
        public void remove(){
            throw new UnsupportedOperationException();
        }   
    }
}

Test.class

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        StuSet stuSet = new StuSet();
        for(int i = 0; i < 16; i++){
            stuSet.add(new Student("123456","某人"));
        }
        System.out.println("目前数组存了: "+stuSet.size()+"个学生对象");
        System.out.println("目前数组的总长度是: "+stuSet.totalSize()+"个索引");
        for(Student s : stuSet){
            System.out.println(s.getId() + " "+s.getName());
        }
    }
}

控制台:

目前数组存了: 16个学生对象
目前数组的总长度是: 20个索引
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人
123456 某人

https://www.cnblogs.com/softidea/p/5167676.html

猜你喜欢

转载自blog.csdn.net/qq_39981500/article/details/79654408