简体   繁体   中英

java- reset list iterator to first element of the list

I need to know how to "reset" LinkedList iterator to its first element.

For example:

LinkedList<String> list;

Iterator iter=list.listIterator;

iter.next();

iter.next();

Over and over again and after many moves of the iterator I need to "reset" the position of iterator. `

I want to ask how I can "reset" my iterator to first element

I know that I can get list iterator of the first element in this way:

iter= list.listIterator(1);

Is this the best solution? or maybe I missed something in Oracle docs?

您可以再次调用listIterator方法以获取指向列表开头的迭代器实例:

iter = list.listIterator();

Best would be not using LinkedList at all, usually it is slower in all disciplines, and less handy. (When mainly inserting/deleting to the front, especially for big arrays LinkedList is faster)

Use ArrayList , and iterate with

int len = list.size();
for (int i = 0; i < len; i++) {
  Element ele = list.get(i);
}

Reset is trivial, just loop again.
If you insist on using an iterator, then you have to use a new iterator:

iter = list.listIterator();

(I saw only once in my life an advantage of LinkedList: i could loop through whith a while loop and remove the first element)

This is an alternative solution, but one could argue it doesn't add enough value to make it worth it:

import com.google.common.collect.Iterables;
...
Iterator<String> iter = Iterables.cycle(list).iterator();
if(iter.hasNext()) {
    str = iter.next();
}

Calling hasNext() will reset the iterator cursor to the beginning if it's a the end.

If the order doesn't matter, we can re-iterate backward with the same iterator using the hasPrevious() and previous() methods:

ListIterator<T> lit = myList.listIterator(); // create just one iterator

Initially the iterator sits at the beginning, we do forward iteration:

while (lit.hasNext()) process(lit.next()); // begin -> end

Then the iterator sits at the end, we can do backward iteration:

while (lit.hasPrevious()) process2(lit.previous()); // end -> begin

What you may actually want to use is an Iterable that can return a fresh Iterator multiple times by calling iterator() .

//A function that needs to iterate multiple times can be given one Iterable:
public void func(Iterable<Type> ible) {
    Iterator<Type> it = ible.iterator(); //Gets an iterator
    while (it.hasNext()) {
        it.next();
    }
    it = ible.iterator(); //Gets a NEW iterator, also from the beginning
    while (it.hasNext()) {
        it.next();
    }
}

You must define what the iterator() method does just once beforehand:

void main() {
    LinkedList<String> list; //This could be any type of object that has an iterator
    //Define an Iterable that knows how to retrieve a fresh iterator
    Iterable<Type> ible = new Iterable<Type>() {
        @Override
        public Iterator<Type> iterator() {
            return list.listIterator(); //Define how to get a fresh iterator from any object
        }
    };
    //Now with a single instance of an Iterable,
    func(ible); //you can iterate through it multiple times.
}

Calling iterator() on a Collection impl, probably would get a new Iterator on each call.

Thus, you can simply call iterator() again to get a new one.


Code

IteratorLearn.java

import org.testng.Assert;
import org.testng.annotations.Test;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

/**
 * Iterator learn.
 *
 * @author eric
 * @date 12/30/18 4:03 PM
 */
public class IteratorLearn {
    @Test
    public void test() {
        Collection<Integer> c = new HashSet<>();
        for (int i = 0; i < 10; i++) {
            c.add(i);
        }

        Iterator it;

        // iterate,
        it = c.iterator();
        System.out.println("\niterate:");
        while (it.hasNext()) {
            System.out.printf("\t%d\n", it.next());
        }
        Assert.assertFalse(it.hasNext());

        // consume,
        it = c.iterator();
        System.out.println("\nconsume elements:");
        it.forEachRemaining(ele -> System.out.printf("\t%d\n", ele));
        Assert.assertFalse(it.hasNext());
    }
}

Output:

iterate:
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

consume elements:
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

What you can do is, set the iterator to the first position mannualy with a while loop.

while(iter.hasPrevious())
{
    iter.previous();
}

when you get out of the loop you will have your iterator at the position 0

sorry any grammar mistakes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM