如何从另一个 class 访问 ListIterator.previous()

How do I access ListIterator.previous() from another class

我在 "Statistics" Class

中有以下迭代
for (Number num : history) {
    // I do stuff with num here
    // ... and, occasionally want to read the previous value
} // for

在我的 "history" class 中,我有一个 ListIterator(而不是 Iterator,因为我也想倒退)。

   @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;
    }

...但我无法弄清楚,当我遍历统计数据中的数字时,如何获取前一个元素 class。

本质上,我想遍历 Numbers,但偶尔会获取前一个 Number(在移过它之后)。

我当然可以存储它,但似乎我应该可以调用 ListIterator.previous(),但我不确定该怎么做?

有什么想法吗?

G

您不能使用 foreach 循环。您需要显式使用迭代器,然后可以调用它的 previous() 方法。

例如

for (ListIterator<Number> itr = history.iterator() ; itr.hasNext() ; ) {
    itr.previous();
}

或者用一个while循环,看起来乱码少一些

ListIterator<Number> itr = history.iterator();
while(itr.hasNext()) {
    itr.previous();
}

实际上,Kayaman 已经以两种不同的方式明确地使用 Iterator 解决了您的问题。

我只是按照您的要求写了一个简单的演示:

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();
            }
         };
      }
   }
}

反汇编其代码,我们有以下片段:

  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

显然 for loop 实际上正在使用

while(history.hasNext()) {
     history.next();
}

迭代history。因此,如果您直接在 for loop 中使用 history.iterator().previous(),您实际上是在创建一个新的 iterator,它将在您的案例中从最开始的 0 开始。

你不想要它,对吧?

明确使用 iterator 将适合您的情况,如下所示:

    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());
        }

    }