晚上好,
我试图在arraylist中的每个像素上调用“ricolora”方法(更改像素的颜色),第一种方法(带有迭代器的方法)不起作用。
它给了我一个异常(java.lang.reflect.InvocationTargetException)。
第二种方法(for循环)工作得很好。你能帮我理解为什么第一种方法不起作用,我认为for循环和迭代器几乎是一回事。
感谢您的帮助。
public class DisegnoManoLibera {
protected final ArrayList<Pixel> pixel;
final public void ricolora(Color c) {
Iterator<Pixel> it = this.pixel.iterator();
int i=0;
while(it.hasNext()){
Pixel pi =(Pixel) it.next();
Pixel gi = new Pixel(pi.getX(), pi.getY(), c);
pixel.remove(i);
pixel.add(i, gi);
i++;
}
}
final public void ricolora(Color c) {
for(int i=0; i<this.pixel.size();i++){
Pixel pip = pixel.get(i);
Pixel gin = new Pixel(pip.getX(), pip.getY(), c);
pixel.remove(i);
pixel.add(i, gin);
}
}
public class Pixel {
final int x;
final int y;
final Color c;
答案 0 :(得分:1)
Hava外观here,这解释了迭代列表的不同方法。
在那里你看到你不应该在使用迭代器(你的pixel.remove(i);
和pixel.add(i, gi);
)时操纵底层列表。
作为替代方案,您可以使用ListIterator,其中包含remove()和add()方法(或者在您的情况下使用set()替换元素)。
for (ListIterator<E> iter = list.listIterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// 3 - can use iter.add(...) to insert a new element into the list
// between element and iter->next()
// 4 - can use iter.set(...) to replace the current element
// ...
}
再次引用另一篇文章:
注意:正如@amarseillan所指出的,这个表单是迭代列表的不好选择,因为get方法的实际实现可能不如使用Iterator时那样有效
答案 1 :(得分:1)
为什么要删除和添加,只需更换值即可?您应该使用List.set(int index, E element)
或ListIterator.set(E e)
。
在迭代集合时,通常不允许修改集合,除非通过迭代器。大多数集合对象的迭代器实现了故障快速逻辑,以防止意外违反该规则。例外是专为多线程并发访问而设计的集合。
因此,如果使用Iterator
,则只能通过该迭代器进行修改。
// Using ListIterator
public final void ricolora(Color c) {
for (ListIterator<Pixel> it = this.pixel.listIterator(); it.hasNext(); ) {
Pixel pi = it.next();
Pixel gi = new Pixel(pi.getX(), pi.getY(), c);
it.set(gi);
}
}
// Using index
public final void ricolora(Color c) {
for (int i = 0; i < this.pixel.size(); i++) {
Pixel pi = this.pixel.get(i);
Pixel gin = new Pixel(pi.getX(), pi.getY(), c);
this.pixel.set(i, gin);
}
}
通常首选Iterator
版本,因为无论List
实施情况如何,它都能表现良好,例如如果List
是LinkedList
,则索引版本的效果会很差。
答案 2 :(得分:0)
代码中为集合获取Iterator
的点,建议不要对调整大小,添加或删除等操作引起的结构修改。如果您需要该功能,可以尝试使用CopyOnWriteArrayList。