Reputation: 1796
In groovy
I can iterate through numbers using that simple syntax:
(1..10).each {
do_domething it
}
What is the shortest syntax to do that in Java? I am now exploring streams and I came up with such an idea:
IntStream.range(0, 10)
.forEach(do_domething());
It is even longer than the traditional way (below), but seems to be more concise.
for (int i = 0; i < 10; i++)
do_domething()
I am just curious if there is shorter and readable way of doing it. I don't know everything about Java so I am just asking, probably there is no such thing, but I would like to make sure.
Upvotes: 0
Views: 463
Reputation: 533700
If you want concise you can use a helper method.
public static void each(int start, int end, IntConsumer consumer) {
IntStream.range(start, end).forEach(consumer);
}
and then you can write
import static java.lang.System.out;
each(0, 10, out::println);
If "each" is a bit verbose you could use a connector character like
public static void ⁀(int start, int end, IntConsumer consumer) {
IntStream.range(start, end).forEach(consumer);
}
public static void main(String... args) {
⁀(0, 10, out::println);
}
prints
0
1
2
3
4
5
6
7
8
9
Upvotes: 1
Reputation: 1245
You can use the so-called "Facetious Arrow" operator (it looks like an arrow "-->") to write the loop slightly more briefly. [Pro Tip: It's not really an arrow]
for (int i=10;i-->0;)doSomething();
For example:
for (int i=10;i-->0;)System.out.println(i);
Prints:
9
8
7
6
5
4
3
2
1
0
Upvotes: 0
Reputation: 23654
You could create a helper function to create an array
public static int[] range(final int length){
return IntStream.range(0, length).toArray();
}
Then using a foreach loop all you need to write is:
for(int i : range(10)) {
do_domething();
}
Upvotes: 0
Reputation: 12022
There are some major differences between those two that do not make them drop in replacements of each other.
A return from a regular for-loop will return from your method, but for the stream/lambda version it returns from the lambda function. See below.
for (int i = 0; i < 10; i++) {
if (i == 5) {
return;//returns from the whole method
}
}
IntStream.range(0, 10).forEach((i -> {
if (i == 5) {
return; //returns only from the lambda
}
}));
Another major difference is how the two code blocks interact with variables. For lambdas to interact with variables that our outside its scope, they need to be final. So the stream/lambda code below won't compile.
String x = "";
for (int i = 0; i < 10; i++) {
if (i == 5) {
x = "5";
}
}
IntStream.range(0, 10).forEach((i -> {
if (i == 5) {
x = "5"; //wont compile
}
}));
There might be other differences between the two. But for me that last one has caused problems that has lead me to continue using the regular for-loop.
Upvotes: 2
Reputation: 37655
If you need to use IntStream.range
repeatedly in one class, you can reduce verbosity by using a static import:
import static java.util.stream.IntStream.range;
Then the syntax becomes
range(0, 10).forEach(...)
Beyond that, there's not much else I can suggest. In my view it is a bit ridiculous that we have to write for(int i = 0; i < n; i++)
repeatedly, but at least it has the advantage of being instantly recognisable.
Upvotes: 2