2020-06-24

jbanana: Badly drawn banana (Default)
2020-06-24 01:02 pm
Entry tags:

Iteration

There are so many ways to iterate in Java. 8~(

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){
    // ???
}
  1. 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 );
    }
  2. You can use while (but who does that?)
    int i = 0
    while ( i < things.size() )
        p.process( things.get( i++ ) );
  3. 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 ++
  4. Still left over from before 1.2:
    Vector v = new Vector(things);
    for ( Enumeration e = v.elements(); e.hasNextElement();  )
        p.process( (Thing)e.nextElement() );
  5. Still left over from before 1.5:
    for ( Iterator i = things.iterator(); i.hasNext();  )
        p.process( i.next() );
  6. 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 );
  7. 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);
            }
        }
    );
  8. Can't be bothered with the lambda variants this time.
    things.stream()
        .forEach(
            p::process
        );
Phew! Hmm - I probably missed some...