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?
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)
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.
}
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.
You can call listIterator
method again to get an instance of iterator pointing at beginning of list:
iter = list.listIterator();
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
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.
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
Source: Stackoverflow.com