自己实现java中Iterator(迭代器功能)
今天躺在床上忽然想到一个问题,迭代器的代码是如何实现的?
于是乎不由自主的爬起来敲两行代码。
list<string> list=new arraylist<>(2); list.add("java"); list.add("c#"); iterator<string> iterator=list.iterator(); while (iterator.hasnext()){ system.out.println(iterator.next()); }
上面的代码是java中很常见的一个迭代的功能。
于是自己也想要写一个泛型类,然后支持这种迭代的功能。
于是乎写了一个类似arraylist的动态数组功能。
package a; import javax.swing.text.html.htmldocument; import java.util.arraylist; import java.util.arrays; import java.util.iterator; public class gys<t>{ private final static int default_capacity =10; private int endindex =0; private object[] elemts; public gys() { this.elemts = new object[default_capacity]; } public t[] add(t t){ if(elemts.length-1< endindex){ int newcapcti= default_capacity *2; elemts= arrays.copyof(elemts,newcapcti); } elemts[endindex++]=t; return (t[])elemts; } public int size(){ return endindex; } public t get(int i){ if(i< endindex){ return (t) elemts[i]; } throw new runtimeexception("索引超出界限"); } public static void main(string[] args) { gys<integer> gys=new gys<>(); gys.add(5); gys.add(45); system.out.println(gys.get(0)); system.out.println(gys.get(1)); } }
上面的代码怎么都没办法实现iterator的功能,在idea下怎么都点不出来iterator的提示;
于是只能去翻阅jdk原码。在arraylist中看到如下的代码。
在arraylist中申明一个内部类itr,并且继承iterator<e>这个接口,然后实现hasnext()和next()方法。
在定义一个方法专门获取迭代器实例。
public iterator<e> iterator() { return new itr(); }
这才明白如何实现迭代器功能。
所以对上面的泛型代码进行改造。
package a; import java.util.arrays; import java.util.iterator; public class gys<t>{ private final static int default_capacity =10; private int endindex =0; private object[] elemts; public gys() { this.elemts = new object[default_capacity]; } public t[] add(t t){ if(elemts.length-1< endindex){ int newcapcti= default_capacity *2; elemts= arrays.copyof(elemts,newcapcti); } elemts[endindex++]=t; return (t[])elemts; } public int size(){ return endindex; } class itr implements iterator<t>{ private int point; private int len; public itr() { this.point=0; this.len=endindex; } @override public boolean hasnext() { return point<endindex?true:false; } @override public t next() { return (t) elemts[point++]; } } public iterator<t> iterator(){ return new itr(); } public t get(int i){ if(i< endindex){ return (t) elemts[i]; } throw new runtimeexception("索引超出界限"); } public static void main(string[] args) { gys<integer> gys=new gys<>(); gys.add(5); gys.add(45); /*system.out.println(gys.get(0)); system.out.println(gys.get(1));*/ iterator iterator= gys.iterator(); while (iterator.hasnext()){ system.out.println(iterator.next()); } } }
怎么样、这个时候就可以对自己的泛型类gys实现迭代器的功能了。
同时另一个疑问也来了,和iterator长得异常相似的接口iterable是干什么的?他和iterator又是什么关系?
翻开源码看看。
源码中可以看出iterable接口提供了一个获取迭代器的接口方法。那么又有哪些类实现了接口呢?
使用idea的ctrl+h快捷键调出查看类的全部继承关系。
我们看到熟悉的collection接口。
看到colllection接口中并没有实现这个接口,依然是一个接口方法。继续向下追踪
看到我们熟悉的arraylist这个类型实现了iterator方法。
从这个角度来看arraylist中的iterator()方法不是空穴来风的,他是通过继承collection和iterable这些接口而来的。
虽然我们上面的泛型类实现了迭代的功能,但是学习了新知识后总要练练手,于是这个时候画蛇添足的对上面的代码继续改造。
package a; import java.util.arrays; import java.util.iterator; public class gys<t> implements iterable<t>{ private final static int default_capacity =10; private int endindex =0; private object[] elemts; public gys() { this.elemts = new object[default_capacity]; } public t[] add(t t){ if(elemts.length-1< endindex){ int newcapcti= default_capacity *2; elemts= arrays.copyof(elemts,newcapcti); } elemts[endindex++]=t; return (t[])elemts; } public int size(){ return endindex; } class itr implements iterator<t>{ private int point; private int len; public itr() { this.point=0; this.len=endindex; } @override public boolean hasnext() { return point<endindex?true:false; } @override public t next() { return (t) elemts[point++]; } } @override public iterator<t> iterator(){ return new itr(); } public t get(int i){ if(i< endindex){ return (t) elemts[i]; } throw new runtimeexception("索引超出界限"); } public static void main(string[] args) { gys<integer> gys=new gys<>(); gys.add(5); gys.add(45); /*system.out.println(gys.get(0)); system.out.println(gys.get(1));*/ iterator iterator= gys.iterator(); while (iterator.hasnext()){ system.out.println(iterator.next()); } } }
写到这想起来之前<<java编程的逻辑>>这本书上说的对于接口的描述:
接口是用于给实现类提供某种能力。
从这个例子中可以很清晰的理解这结论的准确性:
iterable:给实现类提供一个获取迭代器的能力。
iterator:给实现类提供迭代的能力。