轻量级对象
迭代器是一个对象,用于遍历并选择序列中的对象,直接使用迭代器,迭代器不需要考虑容器内部的类型信息,也不需要关心不同容器的底层原理和性质。
迭代器被称为轻量级对象,功能简单有限:1、只能使用iterator()返回容器的迭代器,2、next(),3、hasNext(),4、remove()删除迭代器新近的返回元素。
程序示例展示了利用Iterator不需要确定容器中的类型信息,也不需要关心Collection的类型。
class SimpleIterator{
public static void display(Iterator it){
while(it.hasNext()){
System.out.print(it.next()+" ");
}
while(it.hasNext()){
it.next();
it.remove();
}
}
public static void main(String[] args) {
Integer[] integers=new Integer[]{
1,2,3,4
};
ArrayList<Integer> arrayList =new ArrayList<Integer>(Arrays.asList(integers));
LinkedList<Integer> linkedList=new LinkedList<Integer>(Arrays.asList(integers));
TreeSet<Integer> treeSet=new TreeSet<Integer>(Arrays.asList(integers));
HashSet<Integer> hashSet=new HashSet<Integer>(Arrays.asList(integers));
display(arrayList.iterator());
display(linkedList.iterator());
display(treeSet.iterator());
display(hashSet.iterator());
}
}
ListIterator
ListIterator是一个Iterator的子类。
class SimpleListIterator{
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>(Arrays.asList(1,2,3,4));
System.out.println(list);
ListIterator it=list.listIterator();
while(it.hasNext()) {
System.out.print(it.next()+" "+it.nextIndex()+" ");
}
System.out.println();
while (it.hasPrevious()){
System.out.print(it.previous()+" "+it.previousIndex()+" ");
}
}
}
//output:
//[1, 2, 3, 4]
//1 1 2 2 3 3 4 4
//4 2 3 1 2 0 1 -1
Entry
大量的类都是Iterator类型,主要包括Collection,但是Map并非Iterable,它用Entry表示一对键值。
程序示例用于打印环境变量
class EntryTest{
public static void main(String[] args) {
for(Map.Entry entry:System.getenv().entrySet())
System.out.println(entry);
}
}
Foreach与迭代器
foreach使用Iterable接口移动。Foreach语句之所以能够用于Collection,是因为Collection继承了Iterable接口,所以要想创建在foreach语句中的类需要继承Iterable接口。C++里通过直接传入Iterator是不是直观又简单。
class IteratorClass implements Iterable<String>{
private String[] words="hello world".split(" ");
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
private int index=0;
public boolean hasNext() {
return index<words.length;
}
public String next() {
return words[index++];
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static void main(String[] args) {
for(String s:new IteratorClass())
System.out.println(s);
}
}
//output:
//hello
//world
适配迭代器
我们知道除了list中的Iterator可以双向移动之外,只能前向移动,若想要迭代器产生其他行为就有需要建立其他迭代器,通常做法是给定不同迭代器不同的名字,不然就会覆盖。
程序示例1是我初始的想法,只可以实现Iterator,但是没办法使用foreach语句,foreach语句是使用Ierable接口遍历。
foreach使用Iterable,Iterable应该是想说某个类具有某种迭代的能力,不同迭代的能力产生不同迭代方式,每种能力自己有相应的迭代器。所以我在示例1中使用了reversedIterator()表明是一反向迭代器,示例2中使用reverse()表明是一种能力。
而且foreach语句内部是使用Iterator()方法返回对应的Iterator从而进行操作的(回调——策略设计模式),应该是为了简化利用foreach语句的代价——直接继承接口。
//示例1
class ReversedArray<T> extends ArrayList<T>{
Iterator<T> reversedIterator(){
return new Iterator<T>() {
private int index=size()-1;
public boolean hasNext() {
return index>-1;
}
public T next() {
return get(index--);
}
};
}
}
class Test{
public static void main(String[] args) {
ReversedArray<Integer> array=new ReversedArray<Integer>();
array.addAll(Arrays.asList(1,2,3,4));
// Error: for(Integer integer:array.reversedIterator())
// System.out.println(integer);
}
}
//示例1
class ReversedArray<T> extends ArrayList<T>{
Iterable<T> reverse(){
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private int index=size()-1;
public boolean hasNext() {
return index>-1;
}
public T next() {
return get(index--);
}
};
}
};
}
}
class Test{
public static void main(String[] args) {
ReversedArray<Integer> array=new ReversedArray<Integer>();
array.addAll(Arrays.asList(1,2,3,4));
for(Integer integer:array.reverse)
System.out.println(integer);
}
}
//output:
//4
//3
//2
//1