Java - How do I refer to the previous and next ele

2020-03-16 07:56发布

When I have a for loop, I use the i to refer to the elements of my array, objects, etc.

Like:
Current item: myArray[i]
Next item: myArray[i+1]
Previous item: myArray[i-1]

But at the moment, I'm using a foreach loop ( 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()).

But when it returns true (so it finds what I look for), it should perform the code on the previous and the next item.

Clarification: I have java.awt.Component elements!

4条回答
\"骚年 ilove
2楼-- · 2020-03-16 08:01

Array indexing

If you have an array-like data-structure (e.g. 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. (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.)

The answer offered by Sergey does something like this.

The versatile ListIterator

If you can get your hands on an ListIterator (which is actually quite a big assumption), the answer offered by Suraj could suffice. But do note both next() and previous() moves the iterator position. So if you did something like the following for each loop iteration: prev = previous(); current = next(); next = next(); previous(), you'll end up performing roughly 4 iteration operations per loop. 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.

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.

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.
  • Neither current or next are effectively-final, so cannot be used directly in them fangled Java 8 lambdas.
查看更多
我命由我不由天
3楼-- · 2020-03-16 08:08

The foreach loop won't let you do that. My suggestion is to go back to using the good old fashioned 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;
}
查看更多
神经病院院长
4楼-- · 2020-03-16 08:24
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];
    }
}
查看更多
等我变得足够好
5楼-- · 2020-03-16 08:24

If the data-structure is a List, then you can use a ListIterator directly. The ListIterator is special because it contains both the methods next() and 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
}
查看更多
登录 后发表回答