java篇 常用工具类 0x03:Iterator 与 Iterable 接口

Iterator 接口

Iterator 接口在 java.util 包中。实现了 Iterator 接口的类就可以支持遍历操作。

public interface Iterator<E> {
	// 只需要关注到这两个抽象方法
	boolean hasNext();     // 还有没有下一个元素
	E next();              // 返回下一个元素
}

Iterable 接口

Iterable 接口在 java.lang 包中。实现了 Iterable 接口的类就可以支持 forEach 循环。

import java.util.Iterator;

public interface Iterable<T> {
	// 只需要关注这个抽象方法
	Iterator<T> iterator();    // 得到一个迭代器
}

手动实现 Iterable 接口示例

不实现 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<T> iterator() {  
//        return new Iterator<T>() {         // 由于 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 循环。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值