当前位置: 代码迷 >> Web前端 >> Enumeration 施用中一些经验
  详细解决方案

Enumeration 施用中一些经验

热度:570   发布时间:2012-09-04 14:19:30.0
Enumeration 使用中一些经验
Java代码 复制代码?收藏代码
  1. Vector?v?=?new?Vector(); ??
  2. for(int?i=0;i<10;i++) ??
  3. ????v.add(new?Integer(i)); ??
  4. ??
  5. Enumeration?e?=?v.elements(); ??
  6. ??
  7. while(e.hasMoreElements()) ??
  8. { ??
  9. ????Integer?i?=?(Integer)e.nextElement(); ??
  10. ????v.remove(i); ??
  11. ???????? ??
  12. } ??
  13. ??
  14. System.out.println(v.size());??
        Vector v = new Vector();
        for(int i=0;i<10;i++)
            v.add(new Integer(i));
        
        Enumeration e = v.elements();
        
        while(e.hasMoreElements())
        {
            Integer i = (Integer)e.nextElement();
            v.remove(i);
                
        }
        
        System.out.println(v.size());



如果没去执行这段程序,可能有的人会认为
System.out.println(v.size());
输出来的是0,但实际上是5,为什么会这样的呢?

在回答这个问题前,我们先看看2段代码

Java代码 复制代码?收藏代码
  1. ???public?Enumeration<E>?elements()?{ ??
  2. return?new?Enumeration<E>()?{ ??
  3. ????int?count?=?0; ??
  4. ??
  5. ????public?boolean?hasMoreElements()?{ ??
  6. ????return?count?<?elementCount; ??
  7. ????} ??
  8. ??
  9. ????public?E?nextElement()?{ ??
  10. ????synchronized?(Vector.this)?{ ??
  11. ????????if?(count?<?elementCount)?{ ??
  12. ????????return?(E)elementData[count++]; ??
  13. ????????} ??
  14. ????} ??
  15. ????throw?new?NoSuchElementException("Vector?Enumeration"); ??
  16. ????} ??
  17. }; ??
  18. ???}??
    public Enumeration<E> elements() {
	return new Enumeration<E>() {
	    int count = 0;

	    public boolean hasMoreElements() {
		return count < elementCount;
	    }

	    public E nextElement() {
		synchronized (Vector.this) {
		    if (count < elementCount) {
			return (E)elementData[count++];
		    }
		}
		throw new NoSuchElementException("Vector Enumeration");
	    }
	};
    }



上面这段代码就是v.elements()代码

Java代码 复制代码?收藏代码
  1. public?synchronized?void?removeElementAt(int?index)?{ ??
  2. ????modCount++; ??
  3. ????if?(index?>=?elementCount)?{ ??
  4. ????????throw?new?ArrayIndexOutOfBoundsException(index?+?"?>=?"?+ ??
  5. ?????????????????????????????elementCount); ??
  6. ????} ??
  7. ????else?if?(index?<?0)?{ ??
  8. ????????throw?new?ArrayIndexOutOfBoundsException(index); ??
  9. ????} ??
  10. ????int?j?=?elementCount?-?index?-?1; ??
  11. ????if?(j?>?0)?{ ??
  12. ????????System.arraycopy(elementData,?index?+?1,?elementData,?index,?j); ??
  13. ????} ??
  14. ????elementCount--; ??
  15. ????elementData[elementCount]?=?null;?/*?to?let?gc?do?its?work?*/??
  16. ????}??
public synchronized void removeElementAt(int index) {
	modCount++;
	if (index >= elementCount) {
	    throw new ArrayIndexOutOfBoundsException(index + " >= " +
						     elementCount);
	}
	else if (index < 0) {
	    throw new ArrayIndexOutOfBoundsException(index);
	}
	int j = elementCount - index - 1;
	if (j > 0) {
	    System.arraycopy(elementData, index + 1, elementData, index, j);
	}
	elementCount--;
	elementData[elementCount] = null; /* to let gc do its work */
    }



上面这段代码,就是v.remove(Object o)的主核心代码

分析:
先看第一段代码:

从代码中,我们得知Enumenation.nextElement 会将指针下划到下一个元素

在看第二段代码:

从代码中,我们得知v.remove 进行操作时,是将后面的数组覆盖掉 所要删除元素的位置,最后一个则用null

现在我们理顺下思路吧,

v 里面存放的数是 0 1 2 3 4 5 6 7 8 9

首先e.nextElement() 指针所在位置就是 0,也就是数组的第一个索引

当我们进行v.reomve的时候,后面的数组覆盖了前面的数组

v.remove 处理完后: 1 2 3 4 5 6 7 8 9

这时候,进入下次循环

e.nextElement() 这时候的指针位置就是 2, 而漏过了 1 这个数据,

循环结束后,就漏掉了5个数,

所以,大家在做这样的remove的时候,需要特别注意下