I have the following iteration in a "Statistics" Class
for (Number num : history) {
// I do stuff with num here
// ... and, occasionally want to read the previous value
} // for
Within my "history" class I have a ListIterator (rather than an Iterator as I want to go backwards as well).
@Override
public ListIterator<Number> iterator() {
//System.out.println("In ITERATOR");
ListIterator<Number> it = new ListIterator<Number>() {
private int currentIndex = 0;
@Override
public boolean hasNext() {
return currentIndex < gethistorySize() && spins.get(currentIndex) != null;
}
@Override
public boolean hasPrevious() {
return currentIndex > 0;
}
@Override
public Number next() {
return spins.get(currentIndex++);
}
@Override
public Number previous() {
if(hasPrevious()) {
return spins.get(currentIndex -1);
}
return null;
}
@Override
public int previousIndex() {
return currentIndex -1;
}
@Override
public int nextIndex() {
return currentIndex +1;
}
// The following functions are not implemented as we don't need them for this application
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void set(Number n) {
throw new UnsupportedOperationException();
}
@Override
public void add(Number n) {
throw new UnsupportedOperationException();
}
};
return it;
}
... but I can't figure out, how I can get the previous element, when I am iterating through Numbers from the Statistics class.
Essentially, I want to iterate through Numbers but occasionally get the previous Number (after having moved past it).
I could store it, of course, but it seems that I should be able to call ListIterator.previous(), but I am unsure how to do that?
Any ideas?
G
Actually Kayaman already solved your problem using Iterator
explicitly in two different ways.
I just wrote a simple demo following your request:
public class HelloWorld {
public static void main(String... args) {
int size = 5;
History<Integer> history = new HelloWorld().new History<>(size);
for (int i = 0; i < size; ++i) {
history.add(Integer.valueOf(i));
}
for (Integer a : history) {
System.out.println(a);
if (a % 3 == 1) {
System.out.println(history.iterator().previous());
}
}
}
class History<T> implements Iterable<T> {
T[] arr;
int index;
public History(int theSize) {
index = -1;
arr = (T[]) new Object[theSize];
}
public void add(T t) {
arr[++index] = t;
}
@Override
public ListIterator iterator() {
return new ListIterator() {
int i = 0;
@Override
public boolean hasNext() {
return i <= index;
}
@Override
public Object next() {
return arr[i++];
}
@Override
public boolean hasPrevious() {
return i > 0;
}
@Override
public Object previous() {
return arr[i - 1];
}
@Override
public int nextIndex() {
return 0;
}
@Override
public int previousIndex() {
return 0;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void set(Object o) {
throw new UnsupportedOperationException();
}
@Override
public void add(Object o) {
throw new UnsupportedOperationException();
}
};
}
}
}
And disasseambling its code, we have the following snippet:
43: invokevirtual #9 // Method com/company/HelloWorld$History.iterator:()Ljava/util/ListIterator;
46: astore_2
47: aload_2
48: invokeinterface #10, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
53: ifeq 101
56: aload_2
57: invokeinterface #11, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
62: checkcast #12 // class java/lang/Integer
65: astore_3
66: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream;
69: aload_3
70: invokevirtual #14 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
73: aload_3
74: invokevirtual #15 // Method java/lang/Integer.intValue:()I
77: iconst_3
78: irem
79: iconst_1
80: if_icmpne 98
83: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream;
86: aload_1
87: invokevirtual #9 // Method com/company/HelloWorld$History.iterator:()Ljava/util/ListIterator;
90: invokeinterface #16, 1 // InterfaceMethod java/util/ListIterator.previous:()Ljava/lang/Object;
95: invokevirtual #14 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
Clearly the for loop
is actually using
while(history.hasNext()) {
history.next();
}
to iterate the history
. So if you use history.iterator().previous()
directly in the for loop
, you are actually creating a new iterator
which will start from the very beginning 0
in your case.
And you don't want it, right?
Explicitly using iterator
will suit your case as follows:
ListIterator<Integer> iterator = history.iterator();
while(iterator.hasNext()) {
int a = iterator.next();
System.out.println(a);
if (a % 3 == 1) {
System.out.println(iterator.previous());
}
}