13

昨天,当我回答使用迭代器和删除时出现 ConcurrentModificationException 错误的问题时,我添加了一条通知

当你有 ArrayLists 时使用迭代器不是一个好主意。

您无需深入了解该问题即可回答该问题。

在那里,我有两条评论说我错了。

我的论点:

  1. 使用迭代器时,代码的可读性要差得多。

  2. 有可能引发难以调试的 ConcurrentModificationException。

你能解释一下吗?

问题:我们是否需要在 ArrayList 上使用迭代器?

UPD

这是关于显式使用迭代器。

4

6 回答 6

25

使用 ArrayLists 的迭代器的一个重要用例是当您想要在迭代时删除元素。您只有三个安全的解决方案:

  • 使用迭代器及其remove方法
  • 复制要保留在另一个列表中的元素
  • 有索引的丛林

假设您在迭代时不这样做,使用迭代器add避免.ConcurrentModificationException

可读性论证是主观的。就我个人而言,我没有发现一个明确声明的迭代器可读性较差。这并不重要,因为迭代器是同时迭代和删除的安全方式。

于 2013-04-05T06:58:40.167 回答
15

没有一个答案似乎解决了迭代器的原因。创建迭代器设计模式是因为对象应该控制自己的状态(除了可能只有公共属性的值对象)。

假设我们有一个包含数组的对象,并且您在该对象中有一个接口来向该数组添加项目。但是你已经做了这样的事情:

class MyClass
{
    private ArrayList<Item> myList;

    public MyClass()
    {
        myList = new ArrayList();
    }

    public addItem( Item item )
    {
         item.doSomething(); // Lets say that this is very important before adding the item to the array.
         myList.add( item );
    }
}

现在,如果我在上面的类中有这个方法:

public ArrayList getList()
{
    return myList;
}

有人可以通过此方法获取对 myList 的引用并将项目添加到数组中,而无需调用 item.doSomething(); 这就是为什么你不应该返回对数组的引用,而是返回它的迭代器。可以从数组中获取任何项目,但不能操作原始数组。所以 MyClass 对象仍然控制着它自己的状态。

这就是发明迭代器的真正原因。

于 2015-01-16T13:17:40.190 回答
2

是的,我们需要。ArrayList 只是 List 接口的一个实现,因此您的代码通常会处理一个列表,甚至不知道它是一个 ArrayList。此外,新的 for 循环语法在内部使用迭代器。

于 2013-04-05T07:01:16.043 回答
1

检查这篇文章: http ://www.xyzws.com/javafaq/what-is-the-advantage-of-using-an-iterator-compared-to-the-getindex-method/19

使用迭代器将避免在 LinkedList 上使用 get(index) 的错误(非常慢)。当 list 的实现未知时才有意义,只需使用 iterator。关于 ArrayList,使用迭代器仍将通过 get(index) 实现最接近的性能。

因此,在性能方面使用迭代器进行迭代是一种很好的做法。

于 2013-10-03T04:13:21.787 回答
0

您可能正在谈论显式使用迭代器(因为 : 运算符也在幕后使用迭代器)。

假设您想让两个“指针”遍历数组,但速度取决于实际元素值。如果不显式使用迭代器(当然也没有 elementAt),你将如何做到这一点。

例如(伪代码):

element1 = first element;
element2 = first element;
while(element1.hasNext && element2.hasNext)
{
    if(element1 * 2 < element)
    {
        element2 = element2.next;
    }
    else
    {
        element1 = element1.next;
    }

    //do something with the pair of elements
}
于 2013-04-05T07:02:02.740 回答
-1

使用迭代器时,代码的可读性要差得多。

这完全是你的意见,我不同意。

有可能引发难以调试的 ConcurrentModificationException。

无论您是否使用迭代器,这都可能存在。该异常告诉你一些有用的代码,否则你可能会完全错过,这更难调试。

就个人而言,我更喜欢能够在 ArrayList 和 LinkedList 之间准确编写代码,并让编译器或 API 实现细节。

道德是你不应该把你自己不受支持的观点当作既定事实。

于 2013-04-05T09:13:16.840 回答