[英]Performance of traditional for loop vs Iterator/foreach in Java
[英]Java Iterator vs for loop
晚上好,
我試圖在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;
在這里查看一下 ,這說明了迭代列表的不同方法。 在那里,您看到不應該在使用迭代器時操作基礎列表(您的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指出的那樣,這種形式對於迭代List來說是一個糟糕的選擇,因為get方法的實際實現可能不如使用Iterator時那樣高效。
當您只需替換值時,為什么要刪除和添加? 您應該使用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
實現如何, Iterator
性能都很好,例如,如果List
是LinkedList
,則索引版本的性能會很差。
不建議在代碼中為集合獲取Iterator
,也不建議由調整大小,添加或刪除集合等操作引起的結構修改。 如果需要該功能,可以嘗試使用CopyOnWriteArrayList 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.