Java迭代器是否持有对链表元素的引用?

Java迭代器是否持有对链表元素的引用?,java,pointers,object,iterator,Java,Pointers,Object,Iterator,我需要有一个列表来保存应用程序中敌方类的几个元素。这将作为一个对象池来提高效率,因为这个特定的类通常会被实例化并终止 到目前为止,我可能会使用链表,因为将非活动元素放在列表的末尾将非常有益。我的问题是:在Java中,迭代器是通过持有对当前元素的引用(对于链表)来提供对当前元素的直接访问,还是迭代到下一个元素需要迭代器从头开始循环(也就是说,这无助于提高效率,比如for循环总是需要返回到链接列表的开头) 从C的角度来看,我的问题是迭代器是否包含指向它正在访问的当前元素的指针,这样它就不必从一开始就

我需要有一个列表来保存应用程序中敌方类的几个元素。这将作为一个对象池来提高效率,因为这个特定的类通常会被实例化并终止

到目前为止,我可能会使用链表,因为将非活动元素放在列表的末尾将非常有益。我的问题是:在Java中,迭代器是通过持有对当前元素的引用(对于链表)来提供对当前元素的直接访问,还是迭代到下一个元素需要迭代器从头开始循环(也就是说,这无助于提高效率,比如for循环总是需要返回到链接列表的开头)

从C的角度来看,我的问题是迭代器是否包含指向它正在访问的当前元素的指针,这样它就不必从一开始就循环来获得访问权


我对此做了一些研究,但还没有找到答案。

它没有在Javadoc中记录,但您可以检查
LinkedList的
listIterator
的实现,并查看它是否包含对列表中当前和下一个元素的引用:

public ListIterator<E> listIterator(int index) {
    return new ListItr(index);
}

private class ListItr implements ListIterator<E> {
    private Entry<E> lastReturned = header;
    private Entry<E> next;
    private int nextIndex;
    private int expectedModCount = modCount;
    ....
公共ListIterator ListIterator(int索引){
返回新的ListItr(索引);
}
私有类ListItr实现ListIterator{
private Entry lastReturned=标题;
下一步是私人进入;
私有int nextIndex;
private int expectedModCount=modCount;
....

它只需迭代LinkedList(从开始或结束)创建
ListIterator
时,由于可以在构建列表时请求
ListIterator
指向列表的特定索引。

是,LinkedList中使用的
Iterator
实现保留对下一个和上一个元素的引用,以实现高效迭代

Java是开源的,您可以自己查看代码

私有类ListItr实现ListIterator{
最后返回的私有节点;
私有节点下一步;
私有int nextIndex;
private int expectedModCount=modCount;
ListItr(整数索引){
//断言isPositionIndex(索引);
next=(索引==大小)?null:节点(索引);
nextIndex=指数;
}
公共布尔hasNext(){
返回nextIndex<大小;
}
公共教育{
checkForComodification();
如果(!hasNext())
抛出新的NoTouchElementException();
lastReturned=next;
next=next.next;
nextIndex++;
return lastReturned.item;
}
...
这将作为一个对象池来提高效率,因为这个特定的类通常会被实例化并终止

我不会使用对象池,除非您的对象非常昂贵或调用次数很多,比如每秒一百万次。注意:使用LinkedList将创建对象以将其添加到列表中,因此您可能不会像您想象的那样节省

到目前为止,我可能会使用链表,因为将非活动元素放在列表的末尾将非常有益

内置LinkedLIst不适合这样做,但创建自己的LinkedLIst可能会起作用。添加到列表末尾的成本很高,但添加到列表开头的成本相对较低。我会这样做,因为顺序不重要

我的问题是,在Java中,迭代器是否通过持有对当前元素的引用(对于链表)来提供对当前元素的直接访问

或者迭代到下一个元素是否需要迭代器从头开始重新循环(即,这无助于提高效率)

也是

从C的角度来看,我的问题是迭代器是否包含指向它正在访问的当前元素的指针,这样它就不必从一开始就循环来获得访问权

我根本不会使用迭代器。这会带来更多的垃圾和开销。但是,如果你需要倒带,你可以使用ListIterator,或者你必须创建一个新的迭代器

迭代到下一个元素是否需要迭代器重新从头开始循环

您可以放心,这并不是真的,因为这将是一个自杀式的设计决策。
Iterator
的整个要点是允许为顺序访问数据结构提供最佳的访问模式


我还必须补充一点:从性能和内存的角度来看,
ArrayList
会更好地为您服务。
LinkedList
所需的额外节点元素会导致很大的开销,此外,链接列表固有的指针跟踪访问模式是缓存不友好的。

这:)还值得注意的是,如果
ListItr
没有保留对当前元素的引用,那么迭代列表(即使使用“for”循环)的代价将非常高昂,并且将在O(n^2)时间内发生,我在哪里可以访问它?过多的O(n^2)时间确实是我所担心的about@SuperHacker您可以下载带有源代码的JDK,并从IDE访问它。或者您可以在线搜索它(例如,您可以在Google上搜索“grep code java LinkedList”@SuperHacker,或者看看我的答案,这个答案有一个链接。嗯,我绝对不会达到每秒一百万。你已经说服我放弃这个物体了pool@SuperHacker我建议您使用内存探查器查看分配最多对象的位置,并找到按大小或数量减少最大对象的方法。创建一个平均对象大约需要30 ns。很好关于对象池,Java的GC策略也倾向于小型短期对象,而不是长期对象,长期对象会变得长期且难以GC。但不太清楚您从一开始就循环--
ListItr时所说的“也是”是什么意思private class ListItr implements ListIterator<E> {
    private Node<E> lastReturned;
    private Node<E> next;
    private int nextIndex;
    private int expectedModCount = modCount;

    ListItr(int index) {
        // assert isPositionIndex(index);
        next = (index == size) ? null : node(index);
        nextIndex = index;
    }

    public boolean hasNext() {
        return nextIndex < size;
    }

    public E next() {
        checkForComodification();
        if (!hasNext())
            throw new NoSuchElementException();

        lastReturned = next;
        next = next.next;
        nextIndex++;
        return lastReturned.item;
    }
  ...