简体   繁体   English

Java - 如何在迭代过程中引用上一个和下一个元素?

[英]Java - How do I refer to the previous and next element during an iteration?

When I have a for loop , I use the i to refer to the elements of my array, objects, etc.当我有一个for 循环时,我使用i来引用我的数组、对象等的元素。

Like:喜欢:
Current item: myArray[i]当前项目: myArray[i]
Next item: myArray[i+1]下一项: myArray[i+1]
Previous item: myArray[i-1]上一项: myArray[i-1]

But at the moment, I'm using a foreach loop ( for (Object elem : col) { ).但目前,我正在使用foreach循环( for (Object elem : col) { )。
How do I refer to the previous item?如何参考上一条?
(I need to do a search an 'array', which I'm doing with for (Object object : getComponents()) . (我需要搜索一个“数组”,我正在使用for (Object object : getComponents())

But when it returns true (so it finds what I look for), it should perform the code on the previous and the next item.但是当它返回 true 时(所以它找到了我要找的东西),它应该对上一个下一个项目执行代码。

Clarification: I have java.awt.Component elements!说明:我有java.awt.Component元素!

If the data-structure is a List, then you can use a ListIterator directly.如果数据结构是 List,那么您可以直接使用ListIterator The ListIterator is special because it contains both the methods next() and previous() ListIterator 很特别,因为它同时包含next()previous() 方法

List list = ...;
ListIterator iter = list.listIterator(); //--only objects of type List has this
while(iter.hasNext()){
    next = iter.next();
    if (iter.hasPrevious()) //--note the usage of hasPrevious() method
       prev = iter.previous(); //--note the usage of previous() method
}

The foreach loop won't let you do that. foreach循环不会让你这样做。 My suggestion is to go back to using the good old fashioned Iterator .我的建议是重新使用老式的Iterator For example例如

final Iterator itr=getComponents().iterator();
Object previous=itr.next();
Object current=itr.next();
while(itr.hasNext()){
    Object next=itr.next();
    //Do something with previous, current, and next.
    previous=current;
    current=next;
}
JButton prev, next, curr;
Component[] arr = getComponents();

for(int i=1;i<arr.length-1;i++) {
    if (yourcondition == true) {
        curr = (JButton) arr[i];
        prev = (JButton) arr[i-1];
        next = (JButton) arr[i+1];
    }
}

Array indexing数组索引

If you have an array-like data-structure (eg an actual array or something like an ArrayList ), then referencing i , i-1 , i+1 will give good performance so there isn't much more to it.如果你有一个类似数组的数据结构(例如一个实际的数组或类似ArrayList东西),那么引用ii-1i+1将提供良好的性能,因此没有更多内容。 (Although having to turn a For-Each Loop into an index counting For Loop isn't very fun and is one of the few caveats.) (尽管必须将 For-Each 循环转换为索引计数 For 循环并不是很有趣,而且是为数不多的警告之一。)

The answer offered by Sergey does something like this.谢尔盖提供的答案是这样的。

The versatile ListIterator多功能ListIterator

If you can get your hands on an ListIterator (which is actually quite a big assumption), the answer offered by Suraj could suffice.如果您可以使用ListIterator (这实际上是一个很大的假设),那么 Suraj 提供的答案就足够了。 But do note both next() and previous() moves the iterator position .但请注意next()previous()移动迭代器 position So if you did something like the following for each loop iteration: prev = previous(); current = next(); next = next(); previous()因此,如果您为每个循环迭代执行以下操作: prev = previous(); current = next(); next = next(); previous() prev = previous(); current = next(); next = next(); previous() prev = previous(); current = next(); next = next(); previous() , you'll end up performing roughly 4 iteration operations per loop. prev = previous(); current = next(); next = next(); previous() ,您最终将在每个循环中执行大约 4 次迭代操作。 This isn't much of a problem if iteration is cheap , and luckily this is often the case for data-structures that offers a ListIterator .如果迭代是便宜的,这不是什么大问题,幸运的是,对于提供ListIterator数据结构来说,这通常是这种情况。

Generic solution通用解决方案

The generic solution for any Iterable (or Iterator ) should make no random lookups (as is possible with an array) or make assumptions regarding performance of next() , which should be called at most N times where N is the number of available elements.任何Iterable (或Iterator )的通用解决方案不应进行随机查找(如使用数组可能)或对next()性能做出假设,最多应调用 N 次,其中 N 是可用元素的数量。

Here's one such implementations:这是一个这样的实现:

final Iterator<E> it = iterable.iterator();

for (E next = (it.hasNext() ? it.next() : null), current = null; next != null;) {
    E previous = current;
    current = next;
    next = it.hasNext() ? it.next() : null;

    // Do something using 'current', 'previous' and 'next'.
    // NB: 'previous' and/or 'next' are null when 'current' is
    // the first and/or last element respectively
}

Mind, this implementation has caveats of its own:请注意,此实现有其自身的警告:

  • It'll break if Iterable contains null elements.如果Iterable包含null元素,它将中断。
  • Neither current or next are effectively-final , so cannot be used directly in them fangled Java 8 lambdas. currentnext都不是有效最终的,因此不能直接在它们中使用古怪的 Java 8 lambdas。

I did this to access the previous and next elements in a list while using enhanced for loop.我这样做是为了在使用增强的 for 循环时访问列表中的上一个和下一个元素。

Here's a quick snippet:这是一个快速片段:

import java.util.ArrayList;
import java.util.List;

class Scratch {

  public static void main(String[] args) {
    List<Integer> myInts = new ArrayList<>();
    myInts.add(1);
    myInts.add(2);
    myInts.add(3);
    myInts.add(4);
    myInts.add(5);

    Integer next = null;
    Integer previous = null;

    for (Integer current: myInts) {
        try {
                previous = myInts.get(myInts.indexOf(current)-1);
            } catch (IndexOutOfBoundsException ignored){
               // ignored
            }
        try {
                next = myInts.get(myInts.indexOf(current)+1);
            } catch (IndexOutOfBoundsException ignored){
                next = null;
            }
        System.out.println("previous = " + previous);
        System.out.println("current = " + current);
        System.out.println("next = " + next);
    }
  }
}

Output:输出:

previous = null
current = 1
next = 2
previous = 1
current = 2
next = 3
previous = 2
current = 3
next = 4
previous = 3
current = 4
next = 5
previous = 4
current = 5
next = null

Yeah!是的! I know, the code's ugly.我知道,代码很丑。 But, it get's the job done.但是,它完成了工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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