【问题标题】:How a java iterator works internally? [closed]java迭代器如何在内部工作? [关闭]
【发布时间】:2016-07-04 02:02:29
【问题描述】:

/* 我有一份员工名单 */

List<Employee> empList=new ArrayList<Employee>();
empList.add(employee1);
empList.add(employee2);
empList.add(employee3);
empList.add(employee4);

/* 我取了一个迭代器 */

Iterator<Employee> empIterator=empList.iterator();

在上面的行中,我试图在列表上获取一个迭代器。我的疑问是迭代器中会有什么(所有列表对象会被复制到其中还是列表对象被克隆或者......我只是一无所知)。帮助我理解这一点。 提前致谢。

【问题讨论】:

  • 自己看代码?全部可用
  • 没有复制,也没有克隆。以ArrayList 为例,迭代器是它的一个内部类,可以完全访问封闭的ArrayList 的元素。
  • 迭代器不会复制您的列表。它只是一个按顺序交付物品的工具。

标签: java collections iterator


【解决方案1】:

迭代器将具有修改底层列表的方法,这是调用迭代器时返回的内部类

如果你查看它的source code,你会发现

 public Iterator<E> iterator() {
     return new Itr();
 }

还有班级Itr

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }

    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
        }
    }

【讨论】:

  • 好吧,这些 cmets 完全出轨了。我已经把它们擦干净了。提醒一下:请不要因为试图帮助他人而侮辱他人。
  • 感谢大家提供的所有信息。
【解决方案2】:

大多数简单的 java 集合的迭代器只保留一个指针,指示迭代器当前在集合中的位置。调用 .next() 将推进迭代器。它不复制元素,只返回集合中的下一个元素。由于集合没有被克隆或复制,因此不通过迭代器(包括通过其他迭代器)对集合进行的任何结构修改(添加或删除元素)都会破坏迭代器,并且尝试使用它很可能会抛出 ConcurrentModificationException .这很简单,内存效率高,适用于绝大多数用例。

并发集合的迭代器(在java.util.concurrent 中)要复杂得多,并且它们的操作方式特定于每个集合,以便在集合发生修改时提供结果。

【讨论】:

  • 并非所有未通过迭代器完成的集合修改都会导致ConcurrentModificationException - 例如,您可以在迭代进行时set 元素没有问题。
猜你喜欢
  • 2020-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-21
  • 2014-08-18
  • 2010-11-16
相关资源
最近更新 更多