List的迭代器使用
- Interable接口
public interface Iterable<T> {
Iterator<T> iterator();
}
- List类继承了该接口,所以有iterator()方法,用于返回一个Iterator对象(接口继承接口不用implements而用extends)
public interface List<T> extends Iterable<T>{
Iterator<T> iterator();
...
}
- Iterator对象有如下功能:
package java.util;
public interface Iterator<T> {
boolean hasNext();
T next();
}
- 类内的Iterator具体实现:
public class ArrayList<T> implements List<T>{
public Iterator<T> iterator() {
return new Itr();
}
private class Itr implements Iterator<T> {
public boolean hasNext() {...}
public T next() {...}
}
}
- 具体的迭代器的使用
List<Integer> friends = new ArrayList<Integer>();
Iterator<Integer> seer = friends.iterator();
while(seer.hasNext()) {
System.out.println(seer.next());
}
或
List<Integer> friends = new ArrayList<Integer>();
for (int x : friends) {
System.out.println(x);
}
为自己创建的类写迭代器
在ArrayList中写:
- 让自己的类
extends Iterable<T>
- 在自己的类内写一个自己的iterator继承自
Iterator<T>
对象(作为嵌套类)
private class KeyIterator implements Iterator<K> {
private int ptr;
public KeyIterator() {
ptr = 0;
}
public boolean hasNext() {
return (ptr != size);
}
public K next() {
K returnItem = keys[ptr];
ptr = ptr + 1;
return returnItem;
}
}
注意,在写自己的迭代器类时,hasnext方法返回的实际上不是这个object还有没有下一个,实际上是当前这个object是不是已经为空了(即,如果是最后一个的后一个,才结束遍历)。
因为每次遍历的时候,在当前位置,都读取next()的值,所以next()返回的值实际上是当前object的值。而当当前object为空时,就结束遍历。
- 在自己的类内写iterator()方法用于返回该迭代器对象
public class ArrayMap<K, V> implements Iterable<K>
@Override
public Iterator<K> iterator() {
return new KeyIterator();
}
}
- main函数使用
- 一个笨办法(用不到步骤3的iterator(),所以用不到步骤1,也用不到步骤2中的KeyIterator继承自Iterator。想要这样使用迭代器,只需要在ArrayList里面实现一个嵌套类KeyIterator):
ArrayMap<String, Integer> am = new ArrayMap<String, Integer>();
am.put("hello", 5);
am.put("syrups", 10);
ArrayMap.KeyIterator ami = am.new KeyIterator();
while (ami.hasNext()) {
System.out.println(ami.next());
}
am.new KeyIterator();
可以实例化am内的非静态嵌套类。
- 一个聪明的办法(按照1,2,3,4实现下来。其中步骤2中的KeyIterator继承自Iterator是为了告诉java这是一个迭代器,从而让java可以自动使用迭代器进行for循环):
ArrayMap<String, Integer> am = new ArrayMap<String, Integer>();
for (String s : am) {
System.out.println(s);
}