import java.util.Enumeration;
import java.util.Vector;
public class Test { private int i = 0;
private boolean isBusy;
public Test(int i, boolean isBusy) {
this.i = i;
this.isBusy = isBusy;
}
public static void main(String[] args) {
Vector vector = new Vector();
for (int i = 0; i < 10; i++) {
vector.addElement(new Test(i, false));
System.out.println("add");
}
Enumeration en = vector.elements();
while (en.hasMoreElements()) {
Test tt = (Test)en.nextElement();
vector.remove(tt);
System.out.println("remove");
// en = vector.elements();
}
}}打开注释正常执行10次,关闭却只能执行5次,但是明明en里面还有5个对象,为什么此时执行hasMoreElements()判断却为false,十分不解。
1.hasMoreElements()是在比较en中保存的i与vector.size()
2.nextElement()调用了vector.elementAt(i++)
不知道上面的猜测对不对~~~
建议楼主改用ArrayList和Iterator。用Iterator接口的remove方法来删除元素,这样就不会出错了。
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 elementData(count++);
}
}
throw new NoSuchElementException("Vector Enumeration");
}
};
}
原来你有10个元素,假设删除第9个
此时Enumeration的计数器=8(第9个),删除一个,vector长度变为9,
下一次hasMoreElements的时候,他用计数器和vector的当前长度比较,发现相同,自然返回false
Test tt = (Test)en.nextElement();
vector.remove(tt);中插入System.out.print(tt.i + " ");//结果是0 2 4 6 8
因为nextElement()方法是返回当前地址中的元素,并指向下一个元素的地址,当你调用vector.remove(tt);时这时就会造成Vector底层数组所存储的对象引用的向前移动,而en所指向的地址并未发生变化,这就会形成1,3,5,7,9这些元素没有被遍历到的现象当你加上en = vector.elements();时就会造成en所指向的地址始终指向第一个元素所在的地址,
又由于remove所引起的移动,则会出现这样的现象System.out.print(tt.i + " ");//结果是0 1 2 3 4 5 6 7 8 9
*
* Removes from the underlying collection the last element returned by the
* iterator (optional operation). This method can be called only once per
* call to <tt>next</tt>. The behavior of an iterator is unspecified if
* the underlying collection is modified while the iteration is in
* progress in any way other than by calling this method.
*
这里可不可以这样理解,remove删除的是Iterator所返回的元素(而这个元素只是Iterator的一个表象值),Iterator的引用同样是保存了Arraylist底层数组的下标;
en = vector.elements(); 这个代码也是临时想到解决这个问题的 意义就不说了 很简单的重置一下指针到开头而已 对于使用iterator来代替的情况 不清楚iterator是否是线程安全的 在处理大数据量的遍历 vector 随即访问 效率比list高得多 而且是线程安全的 vector源码已经写明了 还有就是Enumeration的源码我找到的怎么都是抽象声明 在哪个地方有 谢谢!
源码在Vector类中的elements()中的匿名内部类里
源码在Vector类中的elements()中的匿名内部类里
谢谢 刚才在你说之前找到了 粗略看了下实现 十分感谢! 怎么今天傻逼了去看接口声明了 哈哈