• Tags         
  • 2018-08-01  09:00:13        
  • 91 °C    

    迭代器Iterators在Java的Collection框架中用于逐个检索元素。有三个迭代器。

    枚举Enumeration

    它是用于获取遗留集合(Vector,Hashtable)元素的接口。枚举是JDK 1.0中的第一个迭代器,其余部分包含在具有更多功能的JDK 1.2中。枚举还用于指定SequenceInputStream的输入流。我们可以通过在任何矢量对象上调用vector类的elements()方法来创建Enumeration 对象

    // Here "v" is an Vector class object. e is of
    // type Enumeration interface and refers to "v"
    Enumeration e = v.elements();

    Enumeration接口中有两种方法:

    //测试此枚举是否包含更多元素
     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)。因此它不是一个通用的迭代器。
    • 无法使用Enumeration执行删除操作。
    • 只能进行正向迭代。

     

    迭代器Iterator:

    它是一个通用迭代器,因为我们可以将它应用于任何Collection对象。通过使用Iterator,我们可以执行读取和删除操作。它是Enumeration的改进版本,具有元素移除功能的附加功能。每当我们想要枚举所有Collection框架实现的接口(如Set,List,Queue,Deque)以及所有已实现的Map接口类中的元素时,都必须使用Iterator。Iterator是唯一可用于整个集合框架的游标。

    可以通过调用Collection接口中的iterator()方法来创建Iterator对象。

    // Here "c" is any Collection object. itr is of
    // type Iterator interface and refers to "c"
    Iterator itr = c.iterator();

    Iterator接口定义了三种方法:

    //如果迭代有更多元素,则返回true
     public boolean hasNext();
    
    //返回迭代中的下一个元素
    // 如果没有,它会抛出NoSuchElementException
    //元素存在
    public Object 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]
    

    迭代器的局限性:

    • 只能进行正向迭代。
    • Iterator不支持替换和添加新元素。

     

    ListIterator:

    它仅适用于List集合实现的类,如arraylist,linkedlist等。它提供双向迭代。当我们想要枚举List的元素时,必须使用ListIterator。此游标具有比迭代器更多的功能(方法)。

    可以通过调用List接口中的listIterator()方法来创建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。此外还有六种方法。

    //如果迭代有更多元素,则返回true
    public boolean hasNext();
    
    //与Iterator的next()方法相同
    public Object next();
    
    //返回下一个元素索引 
    //如果列表迭代器,则列出大小
    //位于列表的末尾
    public int nextIndex();
    
    //向后的方向
    
    //如果迭代有更多元素,则返回true
    //向后穿过
    public boolean hasPrevious();
    
    //返回迭代中的前一个元素
    //并且可以抛出NoSuchElementException
    //如果没有更多元素存在
    public Object previous();
    
    //返回前一个元素索引 
    //如果列表迭代器位于,则为-1 
    //列表的开头
    public int previousIndex();
    
    //其他方法
     
    //与Iterator的remove()方法相同
    public void remove();
    
    //替换返回的最后一个元素 
    //具有指定元素的next()或previous() 
    public void set(Object obj);
    
    //将指定的元素插入到列表中
    //在要返回的元素之前的位置 
    // by next(),
    public void add(Object obj);
    

    显然,ListIterator从Iterator继承的三个方法(hasNext()next()remove())在两个接口中完全相同。该hasPrevious()和以前的操作的精确类似物hasNext()未来() 。前一个操作引用(隐式)游标之前的元素,而后者引用游标之后的元素。上一个操作向后移动光标,而下一个向前移动光标。

    ListIterator没有当前元素; 它的光标位置总是位于调用previous()返回的元素和调用next()返回的元素之间

    set()方法可以抛出四个异常

    • UnsupportedOperationException - 如果此列表迭代器不支持set操作
    • ClassCastException: 如果指定元素的类阻止将其添加到此列表中
    • IllegalArgumentException:如果指定元素的某些方面阻止将其添加到此列表中
    • IllegalStateException:如果上次调用next或者之前没有调用next或previous,或者在上次调用next或previous之后调用了remove或add

    add()方法可以抛出三个异常

    • UnsupportedOperationException:如果此列表迭代器不支持add方法
    • ClassCastException:如果指定元素的类阻止将其添加到此列表中
    • IllegalArgumentException:如果此元素的某些方面阻止将其添加到此列表中
    // 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:请注意,最初任何迭代器引用都将指向集合中第一个元素的索引之前的索引。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

    引用类名中的$符号证明使用了内部类的概念并创建了这些类对象。

     
    转载请保留页面地址:https://www.breakyizhan.com/java/5028.html