Reputation: 244
I need an iterator where I can navigate between the items of the list with next() and previous().
ListIterator doesn't work for me because it works with cursor logic like below.
val list = listOf(1,2,3,4,5)
val iterator = list.listIterator()
println(iterator.next()) // 1
println(iterator.next()) // 2
println(iterator.previous()) // 2
According to the example above, output I want 1,2,1
Is there any other method Android provides (Kotlin, Java) except ListIterator for this?
Or how can I do it with safe and clean Kotlin code?
Upvotes: 0
Views: 305
Reputation: 36441
Your requirement is inconsistent, not only with the documentation:
An iterator for lists that allows the programmer to traverse the list in either direction, modify the list during iteration, and obtain the iterator's current position in the list. A ListIterator has no current element; its cursor position always lies between the element that would be returned by a call to
previous()
and the element that would be returned by a call tonext()
. An iterator for a list of length n has n+1 possible cursor positions, as illustrated by the carets (^) below:
Element(0) Element(1) Element(2) ... Element(n-1)
cursor positions: ^ ^ ^ ^ ^
but with the common logic of the nature of an iterator. Once you travelled in a given direction, the exact same length reverse traversal must give you the exact reverse sequence. If not you would be very surprised (the exact reverse sequence of "I visited New-York, then Tokyo", is "I visited Tokyo, then New-York").
So if you really need to get 1,2,1, you just have to add an extra reverse traversal at the beginning:
val list = listOf(1,2,3,4,5);
val iterator = list.listIterator();
println(iterator.next()); // 1
println(iterator.next()); // 2
iterator.previous(); // ignore first element of the backward traversal
println(iterator.previous()); // 1
Upvotes: 3
Reputation: 6266
"... Is there any other method Android provides (Kotlin, Java) except ListIterator for this? ..."
You can encapsulate ListIterator, and intercept the next and previous calls.
Just add the methods as needed.
This is technically a wrapper class.
class ListIterator2<E> {
final ListIterator<E> iterator;
ListIterator2(ListIterator<E> iterator) {
this.iterator = iterator;
}
E next() {
return iterator.next();
}
E previous() {
iterator.previous();
return iterator.previous();
}
}
List<Integer> list = List.of(1, 2, 3, 4, 5);
ListIterator2<Integer> iterator = new ListIterator2<>(list.listIterator());
System.out.println(iterator.next());
System.out.println(iterator.next());
System.out.println(iterator.previous());
Upvotes: 0
Reputation:
Consider what a ListIterator
would do if it worked the way you suggest:
val i = listOf(1,2,3,4,5).listIterator()
while (i.hasNext()) {
println(i.next()) // prints 1-5 in order
}
while (i.hasPrevious()) {
println(i.previous()) // prints 4-1, and then... NoSuchElement?
}
Then consider what next()
would now print.
That behaviour is clearly broken. So, change your expectation and use the existing ListIterator
implementation as it is, in it's correctly implemented way.
Upvotes: 1