Java foreach loop: for (Integer i : list) { ... }

184,042

Solution 1

One way to do that is to use a counter:

ArrayList<Integer> list = new ArrayList<Integer>();
...
int size = list.size();
for (Integer i : list) { 
    ...
    if (--size == 0) {
        // Last item.
        ...
    }
}

Edit

Anyway, as Tom Hawtin said, it is sometimes better to use the "old" syntax when you need to get the current index information, by using a for loop or the iterator, as everything you win when using the Java5 syntax will be lost in the loop itself...

for (int i = 0; i < list.size(); i++) {
    ...

    if (i == (list.size() - 1)) {
        // Last item...
    }
}

or

for (Iterator it = list.iterator(); it.hasNext(); ) {
    ...

    if (!it.hasNext()) {
        // Last item...
    }
}

Solution 2

Sometimes it's just better to use an iterator.

(Allegedly, "85%" of the requests for an index in the posh for loop is for implementing a String join method (which you can easily do without).)

Solution 3

The API does not support that directly. You can use the for(int i..) loop and count the elements or use subLists(0, size - 1) and handle the last element explicitly:

  if(x.isEmpty()) return;
  int last = x.size() - 1;
  for(Integer i : x.subList(0, last)) out.println(i);
  out.println("last " + x.get(last));

This is only useful if it does not introduce redundancy. It performs better than the counting version (after the subList overhead is amortized). (Just in case you cared after the boxing anyway).

Solution 4

Another way, you can use a pass-through object to capture the last value and then do something with it:

List<Integer> list = new ArrayList<Integer>();
Integer lastValue = null;
for (Integer i : list) {
    // do stuff
    lastValue = i;
}
// do stuff with last value
Share:
184,042
cometta
Author by

cometta

Updated on July 09, 2022

Comments

  • cometta
    cometta almost 2 years

    When I use JDK5 like below

    ArrayList<Integer> list = new ArrayList<Integer>();  
         for (Integer i : list) { 
    
          //cannot check if already reached last item
    
       }
    

    on the other hand if I just use an Iterator

    ArrayList<Integer> list = new ArrayList<Integer>();
      for (Iterator i = list.iterator(); i.hasNext();) {
    
              //i can check whether this is last item
              if(i.hasNextItem()){
              }
    
        }
    

    How can I check if I've already reached last item with for (Integer i : list) {

  • Romain Linsolas
    Romain Linsolas over 14 years
    I think he wants to do specific treatment inside the loop when he reaches the last item, not getting the last integer of the list. For that, you can also do list.get(list.size() - 1);
  • Brian Agnew
    Brian Agnew over 14 years
    Shouldn't that be !it.hasNext() to determine the last entry ?
  • Brett
    Brett over 14 years
    And i == list.size()-1 in the other example (iterators are generally easier to get right than indexes, although the syntax is a bit long-winded).
  • Brett
    Brett over 14 years
    Nice, but you should add a check that the list has at least one element (or potentially, is not empty).
  • phtrivier
    phtrivier over 14 years
    Or which you can do with apache commons StringUtils.join ;)
  • Brett
    Brett over 14 years
    phtrivier: If you are already dependent upon Apache Commons Lang. I wouldn't introduce a dependency just for that.
  • Esko
    Esko over 14 years
    I understand, however I'm showing here the general idea of capturing the last object. The question is a bit vague in that sense that he doesn't really say what he wants to do, just how he wants to do it.
  • Alnitak
    Alnitak over 14 years
    +1 for the first example - using a decrementing counter is very efficient
  • Thomas Jung
    Thomas Jung over 14 years
    @Tom - There's still a good old join hack that works with for expressions: String join = "x"; StringBuilder buf = new StringBuilder(); for(Integer i : x) buf.append(i).append(join); String result = buf.substring(0, buf.length() - join.length());
  • Brett
    Brett over 14 years
    Thomas: I prefer: StringBuilder buff = new StringBuilder(); String sep = ""; for (Integer i : x) { buff.append(sep).append(i); sep = "x"; } String str = buff.toString();. No hacky substring.
  • Adriaan Koster
    Adriaan Koster over 14 years
    I also love that trick of changing the seperator after the first iteration. Simple and effective.
  • Kevin Bourrillion
    Kevin Bourrillion over 14 years
    FYI, String.join() seems a likely candidate to be in JDK 7.