原文地址:http://www.geeksforgeeks.org/iterators-in-java
Iterators are used in Collection framework in Java to retrieve elements one by one. There are three iterators.
枚举:
枚举是一种用于从遗留下来的集合(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
枚举的缺点:
- Enumeration is for 遗留下的类型(Vector, Hashtable) only. 因此它不是通用的迭代器。
- 在枚举类型中不能用remove操作。
- 只能用前进方向的迭代。
Iterator must be used whenever we want to enumerate elements in all Collection framework implemented interfaces like Set, List, Queue, Deque and also in all implemented classes of Map interface. Iterator is theonly cursor available for entire collection framework.
Iterator object can be created by calling iterator() method present in Collection interface.
迭代器:通用的迭代器可以用于任何的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]迭代器的缺点:
- 只可以向前迭代。
- 迭代器不支持替换和添加新元素。.
当你想枚举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:我们不会创建f 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)