Is there a shorter way to write a for loop in Java?
Asked Answered
M

7

11

the code is

 for(int i = 0; i < max; i++) {
    //do something
 }

I use this exact code many times when I program, always starting at 0 and using the interval i++. There is really only one variable that changes (max)

It could not be that much shorter, but considering how much this code is used, it would be quite helpful.

I know in python there is the range function which is much quicker to type.

Macadamia answered 6/2, 2017 at 21:42 Comment(8)
Depending on the situation could use a for each loop or Java 8 streams.Belk
If you are using eclipse IDE, there is a short cut for for loops. That way, you can only type a few chars and you are done.Repression
You could also write your own shorthand function doInRange(int max, IntConsumer whatToDo)Cacomistle
@Cacomistle Please write an answer for that. I really like the sound of that pattern.Ninefold
static function for every loop? It isnt a good patter believe me!Footing
I think it just appeals to my love for polymorphism in statically typed languages. And who said they needed to be static functions?Ninefold
How do you want to use it across 100 classes? It would be creepy.Footing
Creepy, but interesting. I can agree that it probably isn't a good idea, but I really want to see it.Ninefold
U
14

When looping through collections, you can use enhanced loops:

int[] numbers = 
 {1,2,3,4,5,6,7,8,9,10};

for (int item : numbers) {
   System.out.println(item);
}
Unshackle answered 6/2, 2017 at 21:45 Comment(2)
True, but what if I want 1000 iterations? Nobody's going to bother to write out 1000 elements of the array. The number of iterations is also fixed at compile time too. --- If only we had a preprocessor! Just kidding, we might as well swap to C++ for that.Ninefold
Well I just used this as an example. The enhanced loop can be used on any collection - the main point is the syntax of for(int item : numbers) as opposed to using something like for(int i = 0; i < collection.size(); i++){} :)Unshackle
F
8

If you use Java 8, you can use IntStream.range(min, max).foreach(i ->{})

Footing answered 6/2, 2017 at 21:45 Comment(10)
The OP specifically asked for a shorter way. By my count, IntStream.range(min, max).foreach(() -> is not shorter than for(int i = 0; i < max; i++) :)Diastyle
very funny... It's just better way to use lambda in Java, more readable. Shorter does not mean better.Footing
I don't personally consider this more readable, either. :) But that gets into the realm of opinion. I've been reading for loops for more than 25 years now, so they're pretty second-nature at this point, especially when they follow the standard "0; < max; ++" pattern.Diastyle
If you spent 25 years reading for loops, you can spend for example 2 days to get into lambda functions in java and streams. It is really useful.Footing
They are useful, but using them as replacement for every for loop you have is a very bad idea. As soon as you have even one level of nesting your code gets completely unreadable.Felafel
Oh, I know about them. I don't find what you wrote less readable, I just don't find it more readable, either. And counting chars, it's certainly not shorter.Diastyle
@Felafel That's why you must do external methods :) Cyclomatic complexity concerns for loops as well.Footing
You may regret looping in this way in a multithreaded application.Leroylerwick
There are also parallel streams. In question there is no information about multithreaded environment.Footing
One advantage of this code is that it protects your "i" variable, discouraging the practice of mutating i to affect the state of the loop. It also encourages better naming of i (you now only have to write i once to create your loop, i.e., as the argument). Thirdly, a non-zero startIdx will be seen by a developer more easily.Pinnatisect
P
6

Since a few people asked for something like this, here are a few things you could do, although whether these are really better is arguable and a matter of taste:

void times(int n, Runnable r) {
    for (int i = 0; i < n; i++) {
        r.run();
    }
}

Usage:

times(10, () -> System.out.println("Hello, world!"));

Or:

void times(int n, IntConsumer consumer) {
    for (int i = 0; i < n; i++) {
        consumer.accept(i);
    }
}

Usage:

times(10, x -> System.out.println(x+1));

Or:

void range(int lo, int hi, IntConsumer consumer) {
    for (int i = lo; i < hi; i++) {
        consumer.accept(i);
    }
}

Usage:

range(1, 11, x -> System.out.println(x));

These are just a few ideas. Designed thoughtfully, placed in a common library, and used consistently, they could make common, idiomatic code terse yet readable. Used carelessly, they could turn otherwise straightforward code into an unmanageable mess. I doubt any two developers would ever agree on exactly where the lines should be drawn.

Pubescent answered 6/2, 2017 at 22:51 Comment(1)
Well the question asked for 'shorter' not 'better' so yes, that would be the perfect solution.Moir
J
4

There is a way to write shorter for loop.

If "for" loop is the concern, you may find this interesting

for(int i = -1; ++i < max;) {
    //do something
 }

Notice that the counter increment was done before the comparison with max is done.

Also notice that the index i starts from -1 instead of normal 0.

Jegger answered 16/8, 2021 at 3:16 Comment(0)
A
1

The for shortcut I thought of is: for (int i : val) which works pretty fine for me. Take as an exemple the following code:

for (int i = 0; x < val.length; i++)
System.out.print(val[i] + ", ");

is equivalent with

for (int i : val)
System.out.print(i + ", ");

After having some research, I found this link with examples for the EnhancedFor. This kind of writing the for loop looks very similar to the way of writing a for in Linux Bash.

Airman answered 9/5, 2018 at 16:23 Comment(1)
Not available for java.Unship
S
0

In many cases max value is unknown (data from files, databases etc.). For me the best is loading everything to List (ArrayList etc.) and use for-each loop. Looping through collections is the best way to short loop syntax in my opinion.

Shelves answered 6/2, 2017 at 22:18 Comment(3)
That's fine if all the data fits in memory, although transforming something that reads from files into something that loads everything to a list first means it must all fit in memory, where before it did not necessarily have to.Pubescent
Yes, but you can load the data partially, and use them in the for-each loop.Sweetbrier
You mean like a heap?Sacrifice
E
0

you can use this way for List's

Normal Mode:

List<String> myList = Arrays.asList(new String[]{"a","b","c","d","e","f"});
for (int i=0;i<myList.size();i++){
    System.out.println(myList.get(i));
}

Short Mode 1:

List<String> myList = Arrays.asList(new String[]{"a","b","c","d","e","f"});
myList.forEach((node)->{
    System.out.println(node);
});

Short Mode 2:

List<String> myList = Arrays.asList(new String[]{"a","b","c","d","e","f"});
for(String node: myList){
   System.out.println(node);
}
Et answered 30/3, 2020 at 1:28 Comment(2)
Even shorter is: myList.forEach(System.out::println);Sideway
Of course, it depends on the number of lines in the loopEt

© 2022 - 2024 — McMap. All rights reserved.