- 浏览: 32122 次
最新评论
-
piper:
or
String str [] = new String [ ...
ArrayList<String>.toArray()的问题 -
piper:
String[] tt=(String[])list.toar ...
ArrayList<String>.toArray()的问题 -
shjy.nicholas:
to limingsky:其实SUN并没有必要在界面上跟MS争 ...
Jdk 6 , 野马, 新特性预览 -
limingsky:
希望Sun还是能够放开桌面,把更多的精力放在J2EE上面,毕竟 ...
Jdk 6 , 野马, 新特性预览 -
jerry.li:
不错,总体来看,进步很大,不过应该是一个过渡版本。
Jdk 6 , 野马, 新特性预览
ArrayList是List接口的一个可变长数组实现。实现了所有List接口的操作,并允许存储null值。除了没有进行同步,ArrayList基本等同于Vector。在Vector中几乎对所有的方法都进行了同步,但ArrayList仅对writeObject和readObject进行了同步,其它比如add(Object)、remove(int)等都没有同步。
1.存储
ArrayList使用一个Object的数组存储元素。
private transient Object elementData[];
ArrayList实现了java.io.Serializable接口,这儿的transient标示这个属性不需要自动序列化。下面会在writeObject()方法中详细讲解为什么要这样作。
2.add和remove
public boolean add(Object o) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = o;
return true;
}
注意这儿的ensureCapacity()方法,它的作用是保证elementData数组的长度可以容纳一个新元素。在“自动变长机制”中将详细讲解。
public Object remove(int index) {
RangeCheck(index);
modCount++;
Object oldValue = elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
RangeCheck()的作用是进行边界检查。由于ArrayList采用一个对象数组存储元素,所以在删除一个元素时需要把后面的元素前移。删除一个元素时只是把该元素在elementData数组中的引用置为null,具体的对象的销毁由垃圾收集器负责。
modCount的作用将在下面的“iterator()中的同步”中说明。
注:在前移时使用了System提供的一个实用方法:arraycopy(),在本例中可以看出System.arraycopy()方法可以对同一个数组进行操作,这个方法是一个native方法,如果对同一个数组进行操作时,会首先把从源部分拷贝到一个临时数组,在把临时数组的元素拷贝到目标位置。
3.自动变长机制
在实例化一个ArrayList时,你可以指定一个初始容量。这个容量就是elementData数组的初始长度。如果你使用:
ArrayList list = new ArrayList();
则使用缺省的容量:10。
public ArrayList() {
this(10);
}
ArrayList提供了四种add()方法,
public boolean add(Object o)
public void add(int index, Object element)
public boolean addAll(Collection c)
public boolean addAll(int index, Collection c)
在每一种add()方法中,都首先调用了一个ensureCapacity(int miniCapacity)方法,这个方法保证elementData数组的长度不小于miniCapacity。ArrayList的自动变长机制就是在这个方法中实现的。
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = new Object[newCapacity];
System.arraycopy(oldData, 0, elementData, 0, size);
}
}
从这个方法实现中可以看出ArrayList每次扩容,都扩大到原来大小的1.5倍。
每种add()方法的实现都大同小异,下面给出add(Object)方法的实现:
public boolean add(Object o) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = o;
return true;
}
4.iterator()中的同步
在父类AbstractList中定义了一个int型的属性:modCount,记录了ArrayList结构性变化的次数。
protected transient int modCount = 0;
在ArrayList的所有涉及结构变化的方法中都增加modCount的值,包括:add()、remove()、addAll()、removeRange()及clear()方法。这些方法每调用一次,modCount的值就加1。
注:add()及addAll()方法的modCount的值是在其中调用的ensureCapacity()方法中增加的。
AbstractList中的iterator()方法(ArrayList直接继承了这个方法)使用了一个私有内部成员类Itr,生成一个Itr对象(Iterator接口)返回:
public Iterator iterator() {
return new Itr();
}
Itr实现了Iterator()接口,其中也定义了一个int型的属性:expectedModCount,这个属性在Itr类初始化时被赋予ArrayList对象的modCount属性的值。
int expectedModCount = modCount;
注:内部成员类Itr也是ArrayList类的一个成员,它可以访问所有的AbstractList的属性和方法。理解了这一点,Itr类的实现就容易理解了。
在Itr.hasNext()方法中:
public boolean hasNext() {
return cursor != size();
}
调用了AbstractList的size()方法,比较当前光标位置是否越界。
在Itr.next()方法中,Itr也调用了定义在AbstractList中的get(int)方法,返回当前光标处的元素:
public Object next() {
try {
Object next = get(cursor);
checkForComodification();
lastRet = cursor++;
return next;
} catch(IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
注意,在next()方法中调用了checkForComodification()方法,进行对修改的同步检查:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
现在对modCount和expectedModCount的作用应该非常清楚了。在对一个集合对象进行跌代操作的同时,并不限制对集合对象的元素进行操作,这些操作包括一些可能引起跌代错误的add()或remove()等危险操作。在AbstractList中,使用了一个简单的机制来规避这些风险。这就是modCount和expectedModCount的作用所在。
5.序列化支持
ArrayList实现了java.io.Serializable接口,所以ArrayList对象可以序列化到持久存储介质中。ArrayList的主要属性定义如下:
private static final long serialVersionUID = 8683452581122892189L;
private transient Object elementData[];
private int size;
可以看出serialVersionUID和size都将自动序列化到介质中,但elementData数组对象却定义为transient了。也就是说ArrayList中的所有这些元素都不会自动系列化到介质中。为什么要这样实现?因为elementData数组中存储的“元素”其实仅是对这些元素的一个引用,并不是真正的对象,序列化一个对象的引用是毫无意义的,因为序列化是为了反序列化,当你反序列化时,这些对象的引用已经不可能指向原来的对象了。所以在这儿需要手工的对ArrayList的元素进行序列化操作。这就是writeObject()的作用。
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
s.defaultWriteObject();
// Write out array length
s.writeInt(elementData.length);
// Write out all elements in the proper order.
for (int i=0; i<size; i++)
s.writeObject(elementData[i]);
}
这样元素数组elementData中的所以元素对象就可以正确地序列化到存储介质了。
对应的readObject()也按照writeObject()方法的顺序从输入流中读取:
private synchronized void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in size, and any hidden stuff
s.defaultReadObject();
// Read in array length and allocate array
int arrayLength = s.readInt();
elementData = new Object[arrayLength];
// Read in all elements in the proper order.
for (int i=0; i<size; i++)
elementData[i] = s.readObject();
}
(Iterator的remove()方法除外),
有一阵子想找这个功能但是没找到只好toArray()后完成了这种功能。。。看来看API不细啊
或者在多线程中对遍历代码进行同步
原来是这么番译的。。。。。汗。。。。
how about the One Piece?
i like One Piece ,but i think the One Piece didn't appear when this article was written
sigh...主贴还是一个转抄,原文在:
http://blog.csdn.net/robertb9527/archive/2004/10/09/129989.aspx
---
找了一圈,全是抄袭的,这种风气真让人郁闷.想和原作者讨论还找不到
同步不是哪一句话
而是看效果
看看头一个用了it 在删除元素之后就不能同步了
而后一个删除元素之后就出现了不同步的问题
我说的同步指得是语言层次的
你这里说的只是针对iterator模式一种不正确的使用而已,这样操作会抛出异常,还谈什么同步呀,
就好象你用静态方法去操作实例变量一样,本身就是错的。
arraylist的iterator()方法 生成的是一个迭代器类(内部类)
用它进行迭代操作的时候,删除元素的操作就不能使用arraylist本身的方法了。
具体原因我们可以看这篇文章:
http://gceclub.sun.com.cn/yuanchuang/week-14/iterator.html
我是说你list.remove(element);改成list.remove(j);应该就可以了 arraylist没有remove(Object obj )这个方法 只有 remove(int i) list接口的重载方法 他实现了后一个 主观臆测应该和实际代码结合起来吧?
不好意思 刚刚看看了 发现 remove(Object obj)在父类AbstractCollection里实现了的 呵呵
另外上面说接口的重载方法实现了一个,另外一个不实现 这种情况也是不允许的。
不过同步我是没发现哦
我是说你list.remove(element);改成list.remove(j);应该就可以了 arraylist没有remove(Object obj )这个方法 只有 remove(int i) list接口的重载方法 他实现了后一个 主观臆测应该和实际代码结合起来吧?
多用测试
总得看一下代码吧 你这里remove的参数是什么?弄错了哦
多用测试
哪有什么同步呀 我是1.4.2版本的
我这里看1.4.2里面的代码是这样的呀 没有同步哦 请问你是什么版本 如果是1.5的话 麻烦说一下 怎么找到他的源代码 我在1.4.2的目录下可以找到 1.5的没看到
1.存储
ArrayList使用一个Object的数组存储元素。
private transient Object elementData[];
ArrayList实现了java.io.Serializable接口,这儿的transient标示这个属性不需要自动序列化。下面会在writeObject()方法中详细讲解为什么要这样作。
2.add和remove
public boolean add(Object o) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = o;
return true;
}
注意这儿的ensureCapacity()方法,它的作用是保证elementData数组的长度可以容纳一个新元素。在“自动变长机制”中将详细讲解。
public Object remove(int index) {
RangeCheck(index);
modCount++;
Object oldValue = elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
RangeCheck()的作用是进行边界检查。由于ArrayList采用一个对象数组存储元素,所以在删除一个元素时需要把后面的元素前移。删除一个元素时只是把该元素在elementData数组中的引用置为null,具体的对象的销毁由垃圾收集器负责。
modCount的作用将在下面的“iterator()中的同步”中说明。
注:在前移时使用了System提供的一个实用方法:arraycopy(),在本例中可以看出System.arraycopy()方法可以对同一个数组进行操作,这个方法是一个native方法,如果对同一个数组进行操作时,会首先把从源部分拷贝到一个临时数组,在把临时数组的元素拷贝到目标位置。
3.自动变长机制
在实例化一个ArrayList时,你可以指定一个初始容量。这个容量就是elementData数组的初始长度。如果你使用:
ArrayList list = new ArrayList();
则使用缺省的容量:10。
public ArrayList() {
this(10);
}
ArrayList提供了四种add()方法,
public boolean add(Object o)
public void add(int index, Object element)
public boolean addAll(Collection c)
public boolean addAll(int index, Collection c)
在每一种add()方法中,都首先调用了一个ensureCapacity(int miniCapacity)方法,这个方法保证elementData数组的长度不小于miniCapacity。ArrayList的自动变长机制就是在这个方法中实现的。
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = new Object[newCapacity];
System.arraycopy(oldData, 0, elementData, 0, size);
}
}
从这个方法实现中可以看出ArrayList每次扩容,都扩大到原来大小的1.5倍。
每种add()方法的实现都大同小异,下面给出add(Object)方法的实现:
public boolean add(Object o) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = o;
return true;
}
4.iterator()中的同步
在父类AbstractList中定义了一个int型的属性:modCount,记录了ArrayList结构性变化的次数。
protected transient int modCount = 0;
在ArrayList的所有涉及结构变化的方法中都增加modCount的值,包括:add()、remove()、addAll()、removeRange()及clear()方法。这些方法每调用一次,modCount的值就加1。
注:add()及addAll()方法的modCount的值是在其中调用的ensureCapacity()方法中增加的。
AbstractList中的iterator()方法(ArrayList直接继承了这个方法)使用了一个私有内部成员类Itr,生成一个Itr对象(Iterator接口)返回:
public Iterator iterator() {
return new Itr();
}
Itr实现了Iterator()接口,其中也定义了一个int型的属性:expectedModCount,这个属性在Itr类初始化时被赋予ArrayList对象的modCount属性的值。
int expectedModCount = modCount;
注:内部成员类Itr也是ArrayList类的一个成员,它可以访问所有的AbstractList的属性和方法。理解了这一点,Itr类的实现就容易理解了。
在Itr.hasNext()方法中:
public boolean hasNext() {
return cursor != size();
}
调用了AbstractList的size()方法,比较当前光标位置是否越界。
在Itr.next()方法中,Itr也调用了定义在AbstractList中的get(int)方法,返回当前光标处的元素:
public Object next() {
try {
Object next = get(cursor);
checkForComodification();
lastRet = cursor++;
return next;
} catch(IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
注意,在next()方法中调用了checkForComodification()方法,进行对修改的同步检查:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
现在对modCount和expectedModCount的作用应该非常清楚了。在对一个集合对象进行跌代操作的同时,并不限制对集合对象的元素进行操作,这些操作包括一些可能引起跌代错误的add()或remove()等危险操作。在AbstractList中,使用了一个简单的机制来规避这些风险。这就是modCount和expectedModCount的作用所在。
5.序列化支持
ArrayList实现了java.io.Serializable接口,所以ArrayList对象可以序列化到持久存储介质中。ArrayList的主要属性定义如下:
private static final long serialVersionUID = 8683452581122892189L;
private transient Object elementData[];
private int size;
可以看出serialVersionUID和size都将自动序列化到介质中,但elementData数组对象却定义为transient了。也就是说ArrayList中的所有这些元素都不会自动系列化到介质中。为什么要这样实现?因为elementData数组中存储的“元素”其实仅是对这些元素的一个引用,并不是真正的对象,序列化一个对象的引用是毫无意义的,因为序列化是为了反序列化,当你反序列化时,这些对象的引用已经不可能指向原来的对象了。所以在这儿需要手工的对ArrayList的元素进行序列化操作。这就是writeObject()的作用。
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
s.defaultWriteObject();
// Write out array length
s.writeInt(elementData.length);
// Write out all elements in the proper order.
for (int i=0; i<size; i++)
s.writeObject(elementData[i]);
}
这样元素数组elementData中的所以元素对象就可以正确地序列化到存储介质了。
对应的readObject()也按照writeObject()方法的顺序从输入流中读取:
private synchronized void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in size, and any hidden stuff
s.defaultReadObject();
// Read in array length and allocate array
int arrayLength = s.readInt();
elementData = new Object[arrayLength];
// Read in all elements in the proper order.
for (int i=0; i<size; i++)
elementData[i] = s.readObject();
}
评论
16 楼
抛出异常的爱
2006-09-28
引用
要确保遍历过程顺利完成,必须保证遍历过程中不更改集合的内容(Iterator的remove()方法除外),因此,确保遍历可靠的原则是只在一个线程中使用这个集合,或者在多线程中对遍历代码进行同步。
(Iterator的remove()方法除外),
有一阵子想找这个功能但是没找到只好toArray()后完成了这种功能。。。看来看API不细啊
或者在多线程中对遍历代码进行同步
原来是这么番译的。。。。。汗。。。。
15 楼
jianfeng008cn
2006-09-28
goncha 写道
When iterating on a multi-thread shared list, make a clone of it and then loop on the copy.
BTW, Is this blogger one of One Piece fans?
BTW, Is this blogger one of One Piece fans?
how about the One Piece?
i like One Piece ,but i think the One Piece didn't appear when this article was written
14 楼
goncha
2006-09-28
When iterating on a multi-thread shared list, make a clone of it and then loop on the copy.
BTW, Is this blogger one of One Piece fans?
BTW, Is this blogger one of One Piece fans?
13 楼
eyejava
2006-09-27
凤舞凰扬 写道
帖子不错,不过问题也有。首先疑惑楼主看得ArrayList的实现代码是哪个公司的?对于一般大众使用的
SUN的JDK或者JRE来说。是有蛮多不同的。或者,楼主用的版本是否是JDK1.6?
我就简单列一下文中的一些问题吧。
1.ArrayList并没有对writeObject和readObject进行同步,因为这两个方法在ArrayList中是私有方法,这两个方法是不会给ArrayList本身调用的,所以也不需要去同步。
2.ArrayList每次扩容,并不是每次都扩大到原来大小的1.5倍。对于新增加的元素,ArrayList首先会尝试扩大1.5倍(记忆中JDK1.3和JDK1.4都是尝试扩大2倍),如果依然小于新增加的容积,方法会直接将容积扩大至原有容积+新增容积。
3.iterator()中的同步 , 楼主也许只是想说明modcount的计数器的检查(而且这个modcount也没有楼主想像得那么强大,它只是相当于一个计数器罢了),但是同步这个词,容易让人跟synchronized相混淆,ArrayList中对于iterator是没有同步保护的。
楼主能花精力去看JDK的源代码,并还很细致,的确不错。不过在写文章时,有些表达就要再雕琢些。否则许多朋友粗略一看,会很容易误解的。
SUN的JDK或者JRE来说。是有蛮多不同的。或者,楼主用的版本是否是JDK1.6?
我就简单列一下文中的一些问题吧。
1.ArrayList并没有对writeObject和readObject进行同步,因为这两个方法在ArrayList中是私有方法,这两个方法是不会给ArrayList本身调用的,所以也不需要去同步。
2.ArrayList每次扩容,并不是每次都扩大到原来大小的1.5倍。对于新增加的元素,ArrayList首先会尝试扩大1.5倍(记忆中JDK1.3和JDK1.4都是尝试扩大2倍),如果依然小于新增加的容积,方法会直接将容积扩大至原有容积+新增容积。
3.iterator()中的同步 , 楼主也许只是想说明modcount的计数器的检查(而且这个modcount也没有楼主想像得那么强大,它只是相当于一个计数器罢了),但是同步这个词,容易让人跟synchronized相混淆,ArrayList中对于iterator是没有同步保护的。
楼主能花精力去看JDK的源代码,并还很细致,的确不错。不过在写文章时,有些表达就要再雕琢些。否则许多朋友粗略一看,会很容易误解的。
sigh...主贴还是一个转抄,原文在:
http://blog.csdn.net/robertb9527/archive/2004/10/09/129989.aspx
---
找了一圈,全是抄袭的,这种风气真让人郁闷.想和原作者讨论还找不到
12 楼
jianfeng008cn
2006-09-27
抛出异常的爱 写道
同步不是哪一句话
而是看效果
看看头一个用了it 在删除元素之后就不能同步了
而后一个删除元素之后就出现了不同步的问题
我说的同步指得是语言层次的
你这里说的只是针对iterator模式一种不正确的使用而已,这样操作会抛出异常,还谈什么同步呀,
就好象你用静态方法去操作实例变量一样,本身就是错的。
arraylist的iterator()方法 生成的是一个迭代器类(内部类)
用它进行迭代操作的时候,删除元素的操作就不能使用arraylist本身的方法了。
具体原因我们可以看这篇文章:
http://gceclub.sun.com.cn/yuanchuang/week-14/iterator.html
11 楼
凤舞凰扬
2006-09-27
帖子不错,不过问题也有。首先疑惑楼主看得ArrayList的实现代码是哪个公司的?对于一般大众使用的
SUN的JDK或者JRE来说。是有蛮多不同的。或者,楼主用的版本是否是JDK1.6?
我就简单列一下文中的一些问题吧。
1.ArrayList并没有对writeObject和readObject进行同步,因为这两个方法在ArrayList中是私有方法,这两个方法是不会给ArrayList本身调用的,所以也不需要去同步。
2.ArrayList每次扩容,并不是每次都扩大到原来大小的1.5倍。对于新增加的元素,ArrayList首先会尝试扩大1.5倍(记忆中JDK1.3和JDK1.4都是尝试扩大2倍),如果依然小于新增加的容积,方法会直接将容积扩大至原有容积+新增容积。
3.iterator()中的同步 , 楼主也许只是想说明modcount的计数器的检查(而且这个modcount也没有楼主想像得那么强大,它只是相当于一个计数器罢了),但是同步这个词,容易让人跟synchronized相混淆,ArrayList中对于iterator是没有同步保护的。
楼主能花精力去看JDK的源代码,并还很细致,的确不错。不过在写文章时,有些表达就要再雕琢些。否则许多朋友粗略一看,会很容易误解的。
SUN的JDK或者JRE来说。是有蛮多不同的。或者,楼主用的版本是否是JDK1.6?
我就简单列一下文中的一些问题吧。
1.ArrayList并没有对writeObject和readObject进行同步,因为这两个方法在ArrayList中是私有方法,这两个方法是不会给ArrayList本身调用的,所以也不需要去同步。
2.ArrayList每次扩容,并不是每次都扩大到原来大小的1.5倍。对于新增加的元素,ArrayList首先会尝试扩大1.5倍(记忆中JDK1.3和JDK1.4都是尝试扩大2倍),如果依然小于新增加的容积,方法会直接将容积扩大至原有容积+新增容积。
3.iterator()中的同步 , 楼主也许只是想说明modcount的计数器的检查(而且这个modcount也没有楼主想像得那么强大,它只是相当于一个计数器罢了),但是同步这个词,容易让人跟synchronized相混淆,ArrayList中对于iterator是没有同步保护的。
楼主能花精力去看JDK的源代码,并还很细致,的确不错。不过在写文章时,有些表达就要再雕琢些。否则许多朋友粗略一看,会很容易误解的。
10 楼
抛出异常的爱
2006-09-27
同步不是哪一句话
而是看效果
看看头一个用了it 在删除元素之后就不能同步了
而后一个删除元素之后就出现了不同步的问题
而是看效果
看看头一个用了it 在删除元素之后就不能同步了
而后一个删除元素之后就出现了不同步的问题
9 楼
jianfeng008cn
2006-09-27
jianfeng008cn 写道
public void test002(){ List list = new ArrayList(); for(int i =0 ; i <10 ; i ++){ list.add("m"+i); } try{ for(int j = 0 ; j < list.size();j++){ String element = (String) list.get(j); System.out.println(element); list.remove(element); } fail(); }catch(Exception e){ assertEquals(e.toString(),"java.util.ConcurrentModificationException"); } }
我是说你list.remove(element);改成list.remove(j);应该就可以了 arraylist没有remove(Object obj )这个方法 只有 remove(int i) list接口的重载方法 他实现了后一个 主观臆测应该和实际代码结合起来吧?
不好意思 刚刚看看了 发现 remove(Object obj)在父类AbstractCollection里实现了的 呵呵
另外上面说接口的重载方法实现了一个,另外一个不实现 这种情况也是不允许的。
不过同步我是没发现哦
8 楼
jianfeng008cn
2006-09-27
public void test002(){ List list = new ArrayList(); for(int i =0 ; i <10 ; i ++){ list.add("m"+i); } try{ for(int j = 0 ; j < list.size();j++){ String element = (String) list.get(j); System.out.println(element); list.remove(element); } fail(); }catch(Exception e){ assertEquals(e.toString(),"java.util.ConcurrentModificationException"); } }
我是说你list.remove(element);改成list.remove(j);应该就可以了 arraylist没有remove(Object obj )这个方法 只有 remove(int i) list接口的重载方法 他实现了后一个 主观臆测应该和实际代码结合起来吧?
7 楼
抛出异常的爱
2006-09-27
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; public class ListMayBeTest extends TestCase { public void test001(){ List list = new ArrayList(); for(int i =0 ; i <10 ; i ++){ list.add("m"+i); } Iterator it = list.iterator(); try{ while (it.hasNext()) { String element = (String) it.next(); System.out.println(element); list.remove(element); } fail(); }catch(Exception e){ assertEquals(e.toString(),"java.util.ConcurrentModificationException"); } } public void test002(){ List list = new ArrayList(); for(int i =0 ; i <10 ; i ++){ list.add("m"+i); } try{ for(int j = 0 ; j < list.size();j++){ String element = (String) list.get(j); System.out.println(element); list.remove(element); } fail(); }catch(Exception e){ assertEquals(e.toString(),"java.util.ConcurrentModificationException"); } } public static void main(String arg[]){ ListMayBeTest test = new ListMayBeTest(); test.test001(); } }
引用
m0(第一个打出来的)
m0
m2
m4
m6
m8
m0
m2
m4
m6
m8
6 楼
jianfeng008cn
2006-09-27
抛出异常的爱 写道
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; public class ListMayBeTest extends TestCase { public void test001(){ List list = new ArrayList(); for(int i =0 ; i <10 ; i ++){ list.add("m"+i); } Iterator it = list.iterator(); try{ while (it.hasNext()) { String element = (String) it.next(); System.out.println(element); list.remove(element); } fail(); }catch(Exception e){ assertEquals(e.toString(),"java.util.ConcurrentModificationException"); } } public static void main(String arg[]){ ListMayBeTest test = new ListMayBeTest(); test.test001(); } }
多用测试
总得看一下代码吧 你这里remove的参数是什么?弄错了哦
5 楼
抛出异常的爱
2006-09-27
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; public class ListMayBeTest extends TestCase { public void test001(){ List list = new ArrayList(); for(int i =0 ; i <10 ; i ++){ list.add("m"+i); } Iterator it = list.iterator(); try{ while (it.hasNext()) { String element = (String) it.next(); System.out.println(element); list.remove(element); } fail(); }catch(Exception e){ assertEquals(e.toString(),"java.util.ConcurrentModificationException"); } } public static void main(String arg[]){ ListMayBeTest test = new ListMayBeTest(); test.test001(); } }
多用测试
4 楼
jianfeng008cn
2006-09-27
private class Itr implements Iterator { /** * Index of element to be returned by subsequent call to next. */ int cursor = 0; /** * Index of element returned by most recent call to next or * previous. Reset to -1 if this element is deleted by a call * to remove. */ int lastRet = -1; /** * The modCount value that the iterator believes that the backing * List should have. If this expectation is violated, the iterator * has detected concurrent modification. */ int expectedModCount = modCount; public boolean hasNext() { return cursor != size(); } public Object next() { checkForComodification(); try { Object next = get(cursor); lastRet = cursor++; return next; } catch(IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public void remove() { if (lastRet == -1) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch(IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
哪有什么同步呀 我是1.4.2版本的
3 楼
抛出异常的爱
2006-09-27
说是arraylist不是同步的
而iterator可能是同步的
例子:
it.next()循环时
不能删除list中的元素。。。。
而iterator可能是同步的
例子:
it.next()循环时
不能删除list中的元素。。。。
2 楼
jianfeng008cn
2006-09-27
/** * Save the state of the <tt>ArrayList</tt> instance to a stream (that * is, serialize it). * * @serialData The length of the array backing the <tt>ArrayList</tt> * instance is emitted (int), followed by all of its elements * (each an <tt>Object</tt>) in the proper order. */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ int expectedModCount = modCount; // Write out element count, and any hidden stuff s.defaultWriteObject(); // Write out array length s.writeInt(elementData.length); // Write out all elements in the proper order. for (int i=0; i<size; i++) s.writeObject(elementData[i]); if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } } /** * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is, * deserialize it). */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject(); // Read in array length and allocate array int arrayLength = s.readInt(); elementData = new Object[arrayLength]; // Read in all elements in the proper order. for (int i=0; i<size; i++) elementData[i] = s.readObject(); }
我这里看1.4.2里面的代码是这样的呀 没有同步哦 请问你是什么版本 如果是1.5的话 麻烦说一下 怎么找到他的源代码 我在1.4.2的目录下可以找到 1.5的没看到
1 楼
java虫
2006-09-27
你的第二个帖子个跟在这个后面就好了,连载一下
能看着方便点。
能看着方便点。
相关推荐
本文将通过一系列的示例来详细介绍如何利用 Java 中的 `java.util.zip` 包进行数据的压缩与解压操作。此外,还将探讨这一技术在网络传输中的应用。 #### 数据压缩算法简介 在深入讨论具体实现之前,我们先简要了解...
Java.util包是Java标准库中的核心包之一,它包含了大量用于通用编程的类和接口,是Java开发中不可或缺的一部分。这个包提供了数据结构、集合框架、事件处理、日期时间、随机数生成、位集以及与I/O流操作相关的辅助...
1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...
#### 一、Java.util.Date与Java.sql.Date的基本概念 在Java编程语言中,处理日期和时间时经常使用到`java.util.Date`和`java.sql.Date`这两个类。它们虽然名字相似,但在实际应用中有很大的区别。 - **`java.util....
Java.util包是Java标准库中的核心包之一,包含了许多用于处理集合、数组、日期时间、随机数等的类。在本文件中,我们主要关注Java.util.ArrayList类,这是一个常用的动态数组实现,它提供了灵活的大小调整和高效的...
jdk源码java.util包,所有类解析,包含整体架构及各个类详解
### Java.util.Date到JSON日期转换详解 在Java中处理日期并将其转换为JSON格式是常见的需求,尤其是在进行网络传输或存储操作时。本篇文章将详细介绍如何将`java.util.Date`对象转换为符合特定格式的JSON字符串,...
Java.util包是Java标准库中的核心包之一,它包含了大量用于日常编程的工具类和接口。这个包在Java 2版本中得到了显著增强,引入了许多重要的数据结构和算法,为Java程序员提供了更丰富的功能。 首先,Java.util包中...
一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用。该类库不提供远程的消息功能,其设计的宗旨是实现一个内存中的消息传递机制. 主要特点有: * All ...
Java API中的`java.util.GregorianCalendar`类是用于处理日期和时间的重要工具,它提供了丰富的功能来满足各种日历操作需求。这个类是基于格里高利历(公历)的,是Java中最常用的日期时间类之一。在给定的压缩包...
标题“java.util.pdf”暗示这是一个关于Java编程语言中util包的文档。由于描述和标签均重复标题,我们可以推断文档重点在于解释和示例展示java.util包中的类与接口。java.util是Java的标准库中的一个包,主要用于...
### Java.util包详解 #### 一、概述 `java.util`包是Java Standard Edition (Java SE)的一个核心组件,提供了大量的实用工具类和接口,帮助开发者处理常见的编程任务,如数据存储、日期时间操作、随机数生成等。该...
在Java中,`java.util.logging.Logger` 是标准的日志框架之一,它提供了基础的日志记录功能。为了使用这一功能,首先需要获得 `java.util.logging.Logger` 的实例。可以通过调用 `Logger` 类中的静态方法 `getLogger...
Java.util包是一个非常重要的标准库之一,其中包含了大量有用的类和接口,为开发者提供了丰富的功能。此包中的类和接口可以分为以下几大类别: 1. **集合框架**: - **Collection**:这是一个接口,所有集合类的根...
当我们需要表示一个完整的日期和时间(例如2023-03-06 15:30:45.123),`java.util.Date`是首选。这个类提供了获取和设置日期、时间的方法,以及格式化日期的工具如`SimpleDateFormat`。 然而,`java.sql.Date`是...
为了简化并发编程的复杂性,Java 5 引入了 `java.util.concurrent` 包,提供了一系列强大的类和接口,帮助开发者更高效地管理多线程任务。 #### 二、`java.util.concurrent` 概览 `java.util.concurrent` 包提供了...
Java.util.concurrent(JUC)是Java平台中的一个核心包,专门用于处理多线程并发问题。这个包包含了大量的工具类和接口,极大地简化了并发编程的复杂性,提高了程序的性能和可伸缩性。本测试源文件主要是针对JUC并发...
Java.util.concurrent是Java 5.0引入的一个重要包,它为多线程编程提供了一组高级并发工具。这个包的设计者是Doug Lea,它的出现是JSR-166的一部分,也被称作Tiger更新。Java.util.concurrent的引入是为了解决传统...
本教程将深入讲解如何利用Java.util包和Java.text包中的类进行日历调整、时间调整以及时间预测。提供的10个源代码文件将帮助你实践并理解这些概念。 首先,让我们关注`Java.util.Calendar`类。这个类是日期和时间的...