JAVA:Enumeration枚举遍历和iterator遍历的区别源码分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Dian1pei2xiao3/article/details/84333902

Enumeration与iterator都是提供对集合元素遍历的接口。

Iterator提供的方法:

boolean hasNext():用来判断当前游标后面是否还存在元素,如果存在就返回true,不存在就返回false。

Object next():先返回当前游标右边的元素,然后游标后移一个位置。

void remove():删除最近返回的元素。

使用:

public static void main(String [] args){
        ArrayList<Integer> arrayList=new ArrayList<Integer>();
        arrayList.add(12);
        arrayList.add(15);
        arrayList.add(45);
        arrayList.add(16);
        Iterator<Integer> iterator = arrayList.iterator();
        while (iterator.hasNext()){
            Integer next=iterator.next();
            System.out.print(next+"  ");
        }
        System.out.println();
    }
}
结果:12  15  45  16  

源码:

   public Iterator<E> iterator() {
        return new Itr();
    }

    
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;//版本号在次体现fail-fast

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }


Enumeration中的两个方法:

boolean hashMoreElements():判断是否有更多的元素可以提取,如果有的话就返回true,否则返回false。

Object nextElement():如果至少存在一个可提供的元素,则返回此枚举的下一个元素。

使用:

public static void main(String [] args) {
        Hashtable<Integer, Integer> hashtable = new Hashtable<Integer, Integer>();
        hashtable.put(11, 12);
        hashtable.put(22, 15);
        hashtable.put(33, 45);
        hashtable.put(44, 16);
        Enumeration<Integer> elements = hashtable.elements();
        while (elements.hasMoreElements()) {
           Integer next= elements.nextElement();
           System.out.print(next+" ");
        }
        System.out.println();
}
结果:16 45 15 12

源码分析: 

   public Enumeration elements() {
        return new HashtableEnumerator(table, false);
    }//通过调用elements方法,创建 HashtableEnumerator实例对象, HashtableEnumerator实现了//Enumeration接口中的hasMoreElements(),nextElement()方法
 class HashtableEnumerator implements Enumeration {
        boolean keys;
        int index;
        HashtableEntry table[];
        HashtableEntry entry;

        HashtableEnumerator(HashtableEntry table[], boolean keys) {
            this.table = table;
            this.keys = keys;
            this.index = table.length;
        }
//获取下一个元素:从hasMoreElements()和nextElement()可以看出hashtable的elements()遍历方式
//首先从后向前遍历table数组,table数组的每个节点都是一个单向链表(entry);然后在依次遍历链表

        public boolean hasMoreElements() {
            if (entry != null) {
                return true;
            }
            while (index-- > 0) {
                if ((entry = table[index]) != null) {
                    return true;
                }
            }
            return false;
        }

        public Object nextElement() {
            if (entry == null) {
                while ((index-- > 0) && ((entry = table[index]) == null));
            }
            if (entry != null) {
                HashtableEntry e = entry;
                entry = e.next;
                return keys ? e.key : e.value;//元素返回是倒着输出
            }
            return null;
        }
    }

}

总结Iterator和Enumeration的重要区别:
1:Enumeration中没有删除方法,只有遍历。
2.Iterator支持fail-fast机制,而Enumeration不支持
Enumeration是JDK1.0添加的接口,使用到它的函数包括Vector和Hashtable等类,这些类都是JDK1.0中加入的,
Enumeration存在的目的就是为他们提供遍历接口。Iterator是JDK1.2才添加的接口,它也是为HashMap,ArrayList
等集合提供遍历接口。Iterator是支持fail-fast机制:当多个线程对同一个集合内容进行操作时,就可能会产生fail-fast事件。
一般情况下使用for循环遍历集合,为什么还需要迭代器或者枚举法遍历集合?

对于含有索引的集合,可以使用for循环,通过下标遍历,Arraylist(有index)和Linkedlist(有next),因此也可以用增强for循环和迭代器,而对于以hashmap,hashtable,hashtree等,因为没有索引,不能使用for循环。用iterator更方便

猜你喜欢

转载自blog.csdn.net/Dian1pei2xiao3/article/details/84333902