Java中的迭代器(Iterators in Java)

来源:互联网 发布:2016青少年犯罪率数据 编辑:程序博客网 时间:2024/06/05 02:45

原文地址: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 Enumerationimport 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:
It is a universal iterator as we can apply it to any Collection object. By using Iterator, we can perform both read and remove operations. It is improved version of Enumeration with additional functionality of remove-ability of a element.

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 elementspublic boolean hasNext();// Returns the next element in the iteration// It throws NoSuchElementException if no more // element presentpublic 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 Iteratorimport 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 elementspublic boolean hasNext();// same as next() method of Iteratorpublic Object next();// Returns the next element index // or list size if the list iterator// is at the end of the listpublic int nextIndex();// Backward direction// Returns true if the iteration has more elements// while traversing backwardpublic boolean hasPrevious();// Returns the previous element in the iteration// and can throws NoSuchElementException// if no more element presentpublic Object previous();// Returns the previous element index //  or -1 if the list iterator is at the // beginning of the listpublic int previousIndex();// Other Methods // same as remove() method of Iteratorpublic 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 ListIteratorimport 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 referencesimport 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$1java.util.Vector$Itrjava.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)




0 0