4 ways to make a for loop in Java

Writed by picodotdev on .
java planeta-codigo programacion
Permanent link Comments

The usual way in Java to do a loop is with a for or while statement but with the addition of iterators in Java 5 it is not necessary to have a variable to keep the index of the loop. Since Java 8, streams have been added that offer other new ways of iterating over the elements of a collection, in the latter case with techniques of functional languages.

Java

Until Java 5 to make a loop from 0 to N elements you had to use a variable to keep a counter, do a comparison to check if the limit had been reached and increase the variable in the next execution. The code was quite verbose and since loops are a basic construction of any programming language it is used many times in any algorithm.

Some of these examples of loops are usable from Java 5, in more recent versions many other new features have been added such as lambdas, streams, methods in interfaces and new API for dates in Java 8, the modularity, improved try-with-resource, jlink or a new publishing model in Java 9, type inference for local variables in Java 10, an HTTP client in Java 11 and other novelties in the Java language and platform.

Loops are one of Java’s basic flow control structures and statement types that allow repeating the execution of a block of statements as long as the repetition condition expression is met, in each iteration of the loop the condition expression is evaluated and when it is not fulfilled, it continues with the next sentence of the program.

for loop

Before Java 5, a for loop from 0 to 5 and a collection was done in the following way, maintaining a variable normally named i that acts as a counter and j if the for loop is nested in another. In addition to the counter variable, it requires setting the condition that allows to exit the loop when the end of the iteration is reached, the condition is very important not to create an infinite loop.

1
2
3
for (int i = 0; i < 5; ++i) {
    System.out.println(i);
}
For.java
1
2
3
4
5
Collection<Integer> = Arrays.asList(0, 1, 2, 3, 4);
Iterable it = collection.iterable();
while (it.hasNext()) {
    System.out.println(it.next());
}
Iterator.java

foreach loop

In Java 5 the for loop was significantly enriched, the foreach loop is an improved for loop with which you can loop through a collection and any object that implements the Iterable interface. This loop has the advantage that there is no need to maintain a variable that acts as a counter, nor does it require establishing a condition to check if the end of the iteration has been reached, this avoids the possibility of creating an infinite loop. With the foreach loop a Collection is traversed as follows.

1
2
3
for (int i : Arrays.asList(0, 1, 2, 3, 4)) {
    logger.info("{}", i);
}
Foreach.java

Loop with Iterable

But the forearch is for collections if you want to make a loop of a fixed number of iterations as in the first case, from 0 to 5, knowing that to use the foreach it is enough that we indicate an object that implements the interface Iterable we can use the following expression and its implementation that has the advantage of not having to include the initial value of the counter, the condition expression and the increment or decrement of the variable. The Counter class implements the Iterable interface and returns an Iterator on the values ​​of the indicated range.

1
2
3
for (Object i : new Counter(0, 5)) {
    System.out.println(i);
}
CounterIterable.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package io.github.picodotdev.blogbitix.javaforeach;

import java.util.Iterator;

public class Counter implements Iterable<Integer> {

    private int start;
    private int end;

    public Counter(int start, int end) {
        this.start = start;
        this.end = end;
    }

    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            private int i = start;

            public boolean hasNext() {
                return i < end;
            }

            public Integer next() {
                return i++;
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }
}
Counter.java

Loop with streams

In Java 8 with the introduction of Stream and IntStream we can use the range and rangeClosed to get a Stream of integers and make a loop with a behavior similar to the previous ones.

1
2
3
IntStream.range(0, 5).forEach( i -> {
    System.out.println(i);
});
Stream.java

The Java 8 Stream are fine to simplify some complex operations but for a simple for loop it has its drawbacks such as significantly obfuscating the stacktrace in case of an exception. Any option can be used, but the first with the traditional for loop is the least recommended, having at our disposal the Counter class with Java 5 or the Stream and lambdas with Java 8.

Example with the different types of loop

The following program shows the four options, its output on the console would be the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package io.github.picodotdev.blogbitix.javaforeach;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.stream.IntStream;

public class Main {

    private static Logger logger = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args) {
        logger.info("for i");
        for (int i = 0; i < 5; i++) {
            logger.info("{}", i);
        }

        logger.info("foreach");
        for (int i : Arrays.asList(0, 1, 2, 3, 4)) {
            logger.info("{}", i);
        }

        logger.info("for counter");
        for (int i : new Counter(0, 5)) {
            logger.info("{}", i);
        }

        logger.info("stream foreach");
        IntStream.range(0, 5).forEach(i -> {
            logger.info("{}", i);
        });
    }
}
Main.java

For any of the ways of doing the for loop the behavior is the same, iterate a finite number of times or over the elements of a collection. Choosing which one to use among the different types of loops depends on the case and personal preferences but also considering the readability and expressiveness of the source code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ ./gradlew run

> Task :run
20:58:11.980 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main for i
20:58:11.981 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 0
20:58:11.981 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 1
20:58:11.981 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 2
20:58:11.981 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 3
20:58:11.982 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 4
20:58:11.982 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main foreach
20:58:11.982 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 0
20:58:11.982 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 1
20:58:11.982 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 2
20:58:11.982 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 3
20:58:11.982 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 4
20:58:11.982 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main for counter
20:58:11.983 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 0
20:58:11.983 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 1
20:58:11.983 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 2
20:58:11.983 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 3
20:58:11.983 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 4
20:58:11.983 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main stream foreach
20:58:11.985 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 0
20:58:11.985 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 1
20:58:11.985 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 2
20:58:11.985 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 3
20:58:11.985 [main] INFO  io.github.picodotdev.blogbitix.javaforeach.Main 4

BUILD SUCCESSFUL in 5s
3 actionable tasks: 3 executed
System.out
Terminal

You can download the example complete source code from the Blog Bitix examples repository hosted on GitHub and test it on your computer by executing the following command:
./gradlew run

Share the article: