Java Iterator vs for循环

时间:2016-01-21 18:16:06

标签: java for-loop iterator

晚上好,

我试图在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;

3 个答案:

答案 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

    // ...
}

再次引用另一篇文章:

  

注意:正如@a​​marseillan所指出的,这个表单是迭代列表的不好选择,因为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实施情况如何,它都能表现良好,例如如果ListLinkedList,则索引版本的效果会很差。

答案 2 :(得分:0)

代码中为集合获取Iterator的点,建议不要对调整大小,添加或删除等操作引起的结构修改。如果您需要该功能,可以尝试使用CopyOnWriteArrayList