原文地址:http://www.geeksforgeeks.org/iterators-in-java
迭代器是在Java中Collection框架中逐个检索元素,这里又三种迭代器。
枚举:
枚举是一种用于从遗留下来的集合(Vector,HashTable)中获取元素的。枚举首先是在JDK 1.0中开始表示的,剩下的包含在JDK 1.2中并包含更多的功能。枚举也用于指定输入流到SequenceInputStream。我们通过调用vector类或者(译者认为是or不是on)任意vector对象下的elements()方法来创建枚举对象。
// 这里"v"是一个Vector类对象。e是枚举接口类型的,并且指向“v”
Enumeration e = v.elements();
也就是说枚举接口有两个方法:
//测试是否这个枚举类型包含更多的元素
public boolean hasMoreElements();
// 返回这个枚举的下一个元素
// 抛出异常:NoSuchElementException
// 如果没有更多的元素表示
public Object nextElement();
// Java program to demonstrate Enumeration
import java.util.Enumeration;
import java.util.Vector;
public class Test
{
public static void main(String[] args)
{
// Create a vector and print its contents
Vector v = new Vector();
for (int i = 0; i < 10; i++)
v.addElement(i);
System.out.println(v);
// At beginning e(cursor) will point to
// index just before the first element in v
Enumeration e = v.elements();
// Checking the next element availability
while (e.hasMoreElements())
{
// moving cursor to next element
int i = (Integer)e.nextElement();
System.out.print(i + " ");
}
}
}
输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0 1 2 3 4 5 6 7 8 9
枚举的缺点:
枚举类型只是针对遗留下的类型(Vector, Hashtable)。 因此它不是通用的迭代器。
在枚举类型中不能用remove操作。
只能用前进方向的迭代。
迭代器:
通用的迭代器可以用于任何的Collection对象。通过用迭代器,我们既可以做读操作,也可做移除操作。它是一种枚举类型的改进版本,这种枚举类型带有元素可移除的附加功能。
无论什么时候,我们想要枚举由接口(如Set, List, Queue, Deque还有所有Map接口的实现类)实现的Collection框架下的元素,我们就得用迭代器。迭代器是唯一可用的游标进入collection框架。
迭代器对象可以通过调用Collection接口中的iterator()方法来创建。
// Here "c" is any Collection object. itr is of
// type Iterator interface and refers to "c"
Iterator itr = c.iterator();
迭代接口定义了3个方法:
// Returns true if the iteration has more elements
public boolean hasNext();
// Returns the next element in the iteration
// It throws NoSuchElementException if no more
// element present
public Object next();
// Remove the next element in the iteration
// This method can be called only once per call
// to next()
public void remove();
remove()方法可能抛出两个异常:
UnsupportedOperationException : 如果这个迭代器不支持remove操作。
IllegalStateException :如果下一个方法还没有被调用,或者在调用下一个方法之后remove方法已经被调用
// Java program to demonstrate Iterator
import java.util.ArrayList;
import java.util.Iterator;
public class Test
{
public static void main(String[] args)
{
ArrayList al = new ArrayList();
for (int i = 0; i < 10; i++)
al.add(i);
System.out.println(al);
// at beginning itr(cursor) will point to
// index just before the first element in al
Iterator itr = al.iterator();
// checking the next element availabilty
while (itr.hasNext())
{
// moving cursor to next element
int i = (Integer)itr.next();
// getting even elements one by one
System.out.print(i + " ");
// Removing odd elements
if (i % 2 != 0)
itr.remove();
}
System.out.println();
System.out.println(al);
}
}
输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0 1 2 3 4 5 6 7 8 9
[0, 2, 4, 6, 8]
迭代器的缺点:
只可以向前迭代。
迭代器不支持替换和添加新元素。.
列表迭代器(ListIterator):
它只用于List collection的实现类,如arraylist, linkedlist等,它提供两个方向的迭代。
当你想枚举List中的元素的时候,你就必须用ListIterator。ListIterator比iterator的方法多。
ListIterator对象可以通过List接口中的listIterator()方法来创建。
// Here "l" is any List object, ltr is of type
// ListIterator interface and refers to "l"
ListIterator ltr = l.listIterator();
ListIterator接口继承于Iterator接口,所以Iterator接口的三个方法在ListIterator都能用。另外ListIterator还有另外6个方法。
// Forward direction
// Returns true if the iteration has more elements
public boolean hasNext();
// same as next() method of Iterator
public Object next();
// Returns the next element index
// or list size if the list iterator
// is at the end of the list
public int nextIndex();
// Backward direction
// Returns true if the iteration has more elements
// while traversing backward
public boolean hasPrevious();
// Returns the previous element in the iteration
// and can throws NoSuchElementException
// if no more element present
public Object previous();
// Returns the previous element index
// or -1 if the list iterator is at the
// beginning of the list
public int previousIndex();
// Other Methods
// same as remove() method of Iterator
public void remove();
// Replaces the last element returned by
// next() or previous() with the specified element
public void set(Object obj);
// Inserts the specified element into the list at
// position before the element that would be returned
// by next(),
public void add(Object obj);
很清楚,ListIterator从Iterator继承过来的三个方法(hasNext(), next(),和remove())在所有的接口中做的事情是一模一样的。hasPrevious()与前驱操作就是hasNext()与next()的模仿。former操作引用到(隐含的)光标(cursor)之前的元素,latter引用到光标之后的元素。previous操作往回移动光标,next是向后移动。
ListIterator没有当前元素这一说;它的游标位置总是在调用previous()返回的元素与调用next()返回的元素之间
set()方法可以抛出四种异常
UnsupportedOperationException:如果集合的操作不支持这种list迭代器
ClassCastException: 如果这个list不允许规定元素的类加入(If the class of the specified element prevents it from being added to this list)
IllegalArgumentException: 如果在有些规定的元素放慢不允许加入到这个list
IllegalStateException: 如果next或者previous被调用,或者在调用next或者previous之后再调用remove或者add方法
add()方法可以抛出三种异常
UnsupportedOperationException: 如果这种list iterator不支持add方法
ClassCastException: 如果这个list不允许规定元素的类加入(If the class of the specified element prevents it from being added to this list)
IllegalArgumentException: 如果由于某些原因这个元素不允许加入到list中
// Java program to demonstrate ListIterator
import java.util.ArrayList;
import java.util.ListIterator;
public class Test
{
public static void main(String[] args)
{
ArrayList al = new ArrayList();
for (int i = 0; i < 10; i++)
al.add(i);
System.out.println(al);
// at beginning ltr(cursor) will point to
// index just before the first element in al
ListIterator ltr = al.listIterator();
// checking the next element availabilty
while (ltr.hasNext())
{
// moving cursor to next element
int i = (Integer)ltr.next();
// getting even elements one by one
System.out.print(i + " ");
// Changing even numbers to odd and
// adding modified number again in
// iterator
if (i%2==0)
{
i++; // Change to odd
ltr.set(i); // set method to change value
ltr.add(i); // to add
}
}
System.out.println();
System.out.println(al);
}
}
输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0 1 2 3 4 5 6 7 8 9
[1, 1, 1, 3, 3, 3, 5, 5, 5, 7, 7, 7, 9, 9, 9]
ListIterator的缺点:它是最强大的迭代器但是只能用于List的实现类,所以它不是一种通用的迭代器。
重要的共同点
1:请注意初始化任何迭代器引用讲指向一个collection的第一个元素的下标(index)。
2:我们不能创建Enumeration, Iterator, ListIterator的对象,因为它们是接口。我们用一些像elements(), iterator(), listIterator()这样的方法创建对象。这些方法拥有匿名的内部类,这些内部类继承于各自的接口并返回这个类的对象。这个可以通过下面的代码来证实,对于更多关于内部类的参考
// Java program to demonstrate iterators references
import java.util.Enumeration;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;
public class Test
{
public static void main(String[] args)
{
Vector v = new Vector();
// Create three iterators
Enumeration e = v.elements();
Iterator itr = v.iterator();
ListIterator ltr = v.listIterator();
// Print class names of iterators
System.out.println(e.getClass().getName());
System.out.println(itr.getClass().getName());
System.out.println(ltr.getClass().getName());
}
}
输出:
java.util.Vector$1
java.util.Vector$Itr
java.util.Vector$ListItr
The $ symbol in reference class name is a proof that concept of inner classes is used and these class objects are created.
Related Articles:
Iterator vs Foreach In Java
Retrieving Elements from Collection in Java (For-each, Iterator, ListIterator & EnumerationIterator)