开发者

Java: Alternative to iterator.hasNext() if using for-each to loop over a collection

开发者 https://www.devze.com 2022-12-12 10:46 出处:网络
I\'m trying to replace an iterator-based loop over a Java list with a for-each statement, but the code uses at some point iterator.hasNext() to check if it reached the last element in the list.

I'm trying to replace an iterator-based loop over a Java list with a for-each statement, but the code uses at some point iterator.hasNext() to check if it reached the last element in the list.

Is there something similar for the for-each alternative?

for (Object current : objectList) {
   if (las开发者_JAVA百科t-element) 
      do-something-special
}


for-each is just syntactic sugar for iterator version and if you check compiled bytecode, then you'll notice that compilator actually change it into iterator version.

With a for-each form you can't check whether you'll have more elements or not. Just stay with explicit iterator use if you need that feature.


In addition to Luno's answer:

Iterator<MyClass> it = myCollection.iterator();
while(it.hasNext()) {
  MyClass myClass = it.next():
  // do something with myClass
}

translates to:

for (MyClass myClass:myCollection) {
  // do something with myClass
}


As others have said - this isn't possible.

Just remember that the foreach construct isn't the be-all and end-all. It was introduced to make the very common task of performing the same operations on each element of a collection simpler to denote.

In your case, you don't want to do exactly the same thing to each element - and thus a foreach loop is not the right tool for the job. Trying to "hack" it into doing this is silly, just use an explicit iterator in a classic for loop.


The foreach loop (or enhanced for loop) does not have facilities to keep track of which element is being iterated on at the moment. There is no way to find out which index of a Collection is being worked on, or whether there are more elements to be processed in an Iterable.

That said, one workaround that would work is to keep a reference to the object which is being iterated on at the moment in the foreach loop.

By keeping a reference of what it being worked on at the current iteration, one would be able to keep the reference once the foreach loop ends, and what is left in the variable will be the last element.

This workaround will only work if-and-only-if the last element is the only element which is needed.

For example:

String lastString = null;

for (String s : new String[] {"a", "b", "c"}) {
    // Do something.

    // Keep the reference to the current object being iterated on.
    lastString = s;
}

System.out.println(lastString);

Output:

c


Unfortunately, the for each idiom does not allow you to check if an element is first or last in the list. This is a known limitation of the for each loop. I suggest you just keep using the iterator.

If you can also check for the first element instead of the last one, for example if you're doing String concatenation, you could change to something like:

boolean first = true;
for (Element e : list) {
  if (!first) {
    //do optional operation
  }
  //do other stuff
  first = false;
}

but I would prefer using the iterator.


If you want to stay with for-each maybe something like this:

if (objectList.indexOf(current)==objectList.size()-1) break;


int nElts = objectList.size();
int n = 0;
for (...) {
  if (++n == nElts) ...

is the best I can think of.


There are two possible cases where you would like to do this.

    You need to do something after the last element has been reached: in this case you just need to put your code outside of the loop.

    
        for(Object item:theLinkedList){
    
        }
        System.out.println("something special")
    
    you need to modify the last element in some way or use information related to the last element. In this case you should use the **LinkedList** to access the last element

    for(Object item:theLinkedList){

    }
    Object last=theLinkedList.getLast();
    System.out.println("last");


yes you can, here's how i would do it if you don't want to use the explicit iterator syntax:

for (Object current : objectList) {
   if (objectList.getLast().equals(current)) 
      do-something-special
}


In Addition to bayer you have to do it a bit different because there is no method getLast(). But instead of it you can use this objectList.size() - 1.

for (Object current : objectList) {
   if (objectList.get(objectList.size() - 1).equals(current)) 
      do-something-special
}


Just save loop repeat count, sample :

    int loop = 0;

    for(Item item : items) {

        if(loop == 0) {
            //Is First Item
        }

        if(loop != items.size()-1) {
            //Has Next Item
        }

        if(loop == items.size()-1) {
            //Is Last Item
        }

        //Must Be Last Statement 
        loop++;
    }

It's similar to for(int i = 0; i < items.size(); i++) loop;

items.size() is used for lists and items.length for arrays;

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号