Streams of elements usually do not allow access to the index value of the current item. To iterate over an array or ArrayList while having access to indexes, use IntStream.range(start, endExclusive).

String[] names = { "Jon", "Darin", "Bauke", "Hans", "Marc" };

IntStream.range(0, names.length)
    .mapToObj(i -> String.format("#%d %s", i + 1, names[i]))
    .forEach(System.out::println);

The [range(start, endExclusive)](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#range-int-int->) method returns another [ÌntStream](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html>) and the [mapToObj(mapper)](<https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#mapToObj-java.util.function.IntFunction->) returns a stream of String.

Output:

1 Jon2 Darin3 Bauke4 Hans5 Marc

This is very similar to using a normal for loop with a counter, but with the benefit of pipelining and parallelization:

for (int i = 0; i < names.length; i++) {
    String newName = String.format("#%d %s", i + 1, names[i]);
    System.out.println(newName);
}