标题:解析Iterator,Iterable,手写迭代器
可以这样理解Iterator,Iterable:
- Iterable接口中,有方法iterator(),使用foreach就需要实现此接口
*对于自己写的一个链表,若是没有实现此接口则会出现编译错误如下:for(Object in:myList) {
//只能通过 java.lang.Iterable 的数组或实例进行迭代
- iterator接口中,有方法hasNext(),next()
一、一个不使用Iterator,Iterable接口的迭代器【故下面的同名方法hashNext(),next(),iterator()没有@Override】
-
FNodeList<Integer>.Itr it = myList.iterator();
其实就是使用对象myList调用了FNodeList中的方法iterator()【该方法返回为一个内部类对象】,返回值为:FNodeList<Integer>.Itr it
-
有了内部类对象的引用it后,使用it.hasNext(),有无下一个值【true,有】
*it.next(),将下一个值取出来,it移动到下一个节点
System.out.println("使用迭代器遍历");
FNodeList<Integer>.Itr it = myList.iterator();
while(it.hasNext()) {
Integer in = it.next();
System.out.print(in+" ");
}
System.out.println();
- 内部类的代码如下: 【在iterator()中,创建内部类对象Itr,使得使用的外部类的字段head为最新的。】
class Itr {
private FNode<T> p;
public Itr() {
p=head;
}
public boolean hasNext() {
return p!=null;
}
public T next() {
FNode<T> s=p;
p=p.next;
return s.info;
}
}
完整代码如下:
package c_Utils.cn.my.com.node2;
import java.util.Iterator;
/**
手写迭代器,
* @author dell
*
*/
class FNode<T>{
public T info;
public FNode<T> next;
public FNode(T info) {
this(info,null);
}
public FNode(T info,FNode<T> next) {
this.info=info;
this.next=next;
}
}
class FNodeList<T> {
private FNode<T> head;
private FNode<T> tail;
class Itr {
private FNode<T> p;
public Itr() {
p=head;
}
public boolean hasNext() {
return p!=null;
}
public T next() {
FNode<T> s=p;
p=p.next;
return s.info;
}
}
public Itr iterator() {
return new Itr();
}
}
public class TestFNodeList {
public static void main(String[] args) {
FNodeList<Integer> myList = new FNodeList<Integer>();
myList.addToHead(1);
myList.addToHead(2);
myList.addToHead(3);
myList.addToHead(4);
System.out.println("使用迭代器遍历");
FNodeList<Integer>.Itr it = myList.iterator();
while(it.hasNext()) {
Integer in = it.next();
System.out.print(in+" ");
}
System.out.println();
}
}
二、使用Iterator 【故下面的同名方法iterator()没有@Override】
- 在上面的基础上,只是多了一个实现此接口,以及iterator()返回的返回类型更改了【Itr–>Iterator】
private class Itr implements Iterator<T>
public Iterator<T> Itr iterator() {
return new Itr();
}
完整代码如下:
/**
手写迭代器 ,规范的
* @author dell
*
*/
class FNode<T>{
public T info;
public FNode<T> next;
public FNode(T info) {
this(info,null);
}
public FNode(T info,FNode<T> next) {
this.info=info;
this.next=next;
}
}
class FNodeList<T>{
private FNode<T> head;
private FNode<T> tail;
private class Itr implements Iterator<T> {
private FNode<T> p;
public Itr() {
p=head;
}
@Override
public boolean hasNext() {
return p!=null;
}
@Override
public T next() {
FNode<T> s=p;
p=p.next;
return s.info;
}
}
public Iterator<T> Itr iterator() {
return new Itr();
}
}
public class TestFNodeList {
public static void main(String[] args) {
FNodeList<Integer> myList = new FNodeList<Integer>();
myList.addToHead(1);
myList.addToHead(2);
myList.addToHead(3);
myList.addToHead(4);
System.out.println("使用迭代器遍历");
Iterator<Integer> it = myList.iterator();
while(it.hasNext()) {
Integer in = it.next();
System.out.print(in+" ");
}
System.out.println();
}
}
三、使用iterator,iterable
1.分析
- 若只使用iterable接口,则@Override方法iterator()时,会因为返回的类型不兼容而编译出错,
返回类型与 Iterable<T>.iterator() 不兼容
- 所以使用Iterable时,需要有Iterator接口
2.操作
在前面一个(二)的基础上,只需要让FNodeList实现此接口Iterable即可
class FNodeList<T> implements Iterable<T> {//使用foreach,就需要实现此接口
完整代码如下:
package c_Utils.cn.my.com.node2;
import java.util.Iterator;
/**
手写迭代器,使用for-each,
* @author dell
*
*/
class FNode<T>{
public T info;
public FNode<T> next;
public FNode(T info) {
this(info,null);
}
public FNode(T info,FNode<T> next) {
this.info=info;
this.next=next;
}
}
class FNodeList<T> implements Iterable<T> {//使用foreach,就需要实现此接口
private FNode<T> head;
private FNode<T> tail;
private class Itr implements Iterator<T> {
private FNode<T> p;
public Itr() {
p=head;
}
@Override
public boolean hasNext() {
return p!=null;
}
@Override
public T next() {
FNode<T> s=p;
p=p.next;
return s.info;
}
}
@Override
public Iterator<T> Itr iterator() {
return new Itr();
}
}
public class TestFNodeList {
public static void main(String[] args) {
FNodeList<Integer> myList = new FNodeList<Integer>();
myList.addToHead(1);
myList.addToHead(2);
myList.addToHead(3);
myList.addToHead(4);
System.out.println("使用for-each遍历");
for(Object in:myList) {//只能通过 java.lang.Iterable 的数组或实例进行迭代
System.out.print(in+" ");
}
System.out.println();
System.out.println("使用迭代器遍历");
Iterator<Integer> it = myList.iterator();
while(it.hasNext()) {
Integer in = it.next();
System.out.print(in+" ");
}
System.out.println();
}
}
四、Java中ArrayList中的部分源码解析如下: