There are so many ways to iterate in Java. 8~(
Suppose that we have
Suppose that we have
class Thing{...} interface Processor{void process(Thing thing);}We want to process each thing. How do we complete this method?
void processAllThings(List<Thing> things, Processor p){ // ??? }
- old skool C-style:
for ( int i = 0; i < things.size(); i++ ) p.process( things.get( i ) );
Bonus variant 1:for ( int i = 0; ; ) { if ( i >= things.size() ) break; p.process( things.get( i++ ) ); // careful where you put the ++ }
Bonus(?!) variant 2:for ( int i = 0; ; ) { try { p.process( things.get( i++ ) ); } catch ( IndexOutOfBoundsException x ) { // spot the bug break; } }
Bonus(?!) variant 3:for ( int i = 0; ; ) { Thing thing = null; try { thing = things.get( i++ ); } catch ( IndexOutOfBoundsException x ) { break; } p.process( thing ); }
- You can use
while
(but who does that?)int i = 0 while ( i < things.size() ) p.process( things.get( i++ ) );
- You can use
do... while
(but who does that?)int i = 0 do p.process( things.get( i ) ); while ( ++i < things.size() ); // careful where you put the ++
- Still left over from before 1.2:
Vector v = new Vector(things); for ( Enumeration e = v.elements(); e.hasNextElement(); ) p.process( (Thing)e.nextElement() );
- Still left over from before 1.5:
for ( Iterator
i = things.iterator(); i.hasNext(); ) p.process( i.next() ); - Still left over from before 1.8:
for ( Thing thing : things ) p.process ( thing );
Bonus variant for newer Java versions:for ( var thing : things ) p.process ( thing );
- Arrived in 1.8:
things.forEach( p::process );
Bonus variant 1:things.forEach( thing -> p.process(thing); );
Bonus variant 2:things.forEach( new Consumer
(){ @Override public void accept(Thing thing){ p.process(thing); } } ); - Can't be bothered with the lambda variants this time.
things.stream() .forEach( p::process );