Is there a concise way to iterate over a stream whilst having access to the index in the stream?
String[] names = {\"Sam\",\"Pamela\", \"Dave\", \"Pascal\",
The Java 8 streams API lacks the features of getting the index of a stream element as well as the ability to zip streams together. This is unfortunate, as it makes certain applications (like the LINQ challenges) more difficult than they would be otherwise.
There are often workarounds, however. Usually this can be done by "driving" the stream with an integer range, and taking advantage of the fact that the original elements are often in an array or in a collection accessible by index. For example, the Challenge 2 problem can be solved this way:
String[] names = {"Sam", "Pamela", "Dave", "Pascal", "Erik"};
List nameList =
IntStream.range(0, names.length)
.filter(i -> names[i].length() <= i)
.mapToObj(i -> names[i])
.collect(toList());
As I mentioned above, this takes advantage of the fact that the data source (the names array) is directly indexable. If it weren't, this technique wouldn't work.
I'll admit that this doesn't satisfy the intent of Challenge 2. Nonetheless it does solve the problem reasonably effectively.
EDIT
My previous code example used flatMap
to fuse the filter and map operations, but this was cumbersome and provided no advantage. I've updated the example per the comment from Holger.