【问题标题】:java iterator with index parameter带索引参数的java迭代器
【发布时间】:2015-07-19 09:05:11
【问题描述】:

您好,LinkedList 的普通迭代器如下所示,但是,我们如何构建一个返回从指定索引开始的迭代器的迭代器?我们如何构建:

public Iterator<E>iterator(int index)???  

谢谢! 普通迭代器:

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

private class ListIterator implements Iterator<E>
    {
        private Node current;

        public ListIterator()
        {
            current = head; // head in the enclosing list
        }
        public boolean hasNext()
        {
            return current != null;
        }
        public E next()
        {
            E ret = current.item;
            current = current.next;
            return ret;
        }
        public void remove() { /* omitted because optional */ }
    }

【问题讨论】:

  • 如果您不打算在迭代时从Colleciton 中删除元素,您宁愿只使用传统的for 循环。
  • LinkedList 有一个方法 listIterator(int) 它完全符合您的要求。这里是link to docs

标签: java linked-list iterator


【解决方案1】:

你可以调用普通的iterator()方法,然后多次调用next()

public Iterator<E> iterator(int index) {
    Iterator<E> iterator = iterator();
    for (int i = 0; i < index && iterator.hasNext(); i++) {
        iterator.next();
    }
    return iterator;
}

【讨论】:

  • 您不想使用传统的for 循环遍历集合并跳过您不感兴趣的索引吗?
  • @ChetanKinger:我不确定你的意思 - 这不是我通常会写的方法,但它回答了被问到的问题......
  • 我会尝试通过代码详细说明:for(int i=0;i&lt;collection.size();++i) { if(i&gt;index) { break; } else { //dosomething } }。为什么首先要创建迭代器?这样做有意义的唯一原因是您计划在迭代时删除元素。
  • @JonSkeet 谢谢你,乔恩!帮了大忙,你是个传奇!
【解决方案2】:

这是如何实现此类iterator 的启动示例,但建议还创建或扩展适当的interface 并使此对象实现此interface 以进行约定。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IterableObject {

    private List<String> values = new ArrayList<String>();


    public Iterator<String> getIterator(final int index) {

        Iterator<String> it = new Iterator<String>() {

            private int current = index;

            @Override
            public void remove() {
                // TODO Auto-generated method stub

            }

            @Override
            public String next() {
                String value = values.get(current);
                current++;
                return value;
            }

            @Override
            public boolean hasNext() {
                if(values.size() > current){
                    return true;
                }else{
                    return false;
                }

            }
        };

        return it;
    }

}

更新

根据 cmets,我为 LinkedList 编写了一个迭代器

public Iterator<String> getIterator(final int index) {


        Iterator<String> it = new Iterator<String>() {

            private Object currentObject = null;

            {
                /*initialize block where we traverse linked list 
                  that it will pointed to object at place index*/
                System.out.println("initialize" + currentWord);
                for(int i = 0; currentObject.next != null && i < index; i++, currentObject = currentObject.next)
                    ;

            } 


            @Override
            public void remove() {
                // TODO Auto-generated method stub

            }

            @Override
            public String next() {
                Object obj = currentObject.next;
                currentObject = currentObject.next;
                return obj;
            }

            @Override
            public boolean hasNext() {
                return currentObject.next != null;

            }
        };

        return it;
    }

因为IteratorAnonymous class 的对象,我们不能使用constructor,但可以在初始化块中对其进行初始化,请看这个答案:https://stackoverflow.com/a/362463/947111 我们在开始时遍历它一次(对于 C style) 所以它将指向currentObject。所有剩下的代码都是自我解释的。

【讨论】:

  • @ChetanKinger,是的,我犯了错误并已修复。谢谢你指点我。
  • 刚刚试用了您的代码,它的工作原理与宣传的一样。这是比接受的答案 IMO 更好的方法。
  • @ChetanKinger, ups 我不小心删除了你的评论 :( 对不起
  • 这对于链表来说效率极低,因为values.get(index)每次执行获取指定元素时都需要从头开始遍历链表。
  • hasNext 方法可以更简洁地写成这样的主体:return values.get(current) != null;
猜你喜欢
  • 1970-01-01
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多