REGAL
REGAL

Reputation: 326

Are there cases where while/do-while must be used instead of for?

This is a long running debate between me and my teacher. Can there be a situation where a for loop absolutely cannot be used in place of a while/do-while loop? In other words, is there a specific case where a for-loop will not work in place of a while loop; is while/do-while in any way "distinct" from for?

Upvotes: 23

Views: 2330

Answers (4)

arshajii
arshajii

Reputation: 129507

No, there is no such situation. Every do-while loop can be written in terms of a while-loop (by executing the body once before the loop) and vice versa. In turn, every while-loop

while (X) {
    ...
}

can be written as

for (; X;) {
    ...
}

i.e. we omit an initialization and an increment statement. We can also convert from a for back to a while by correctly placing the initialization and increment.

In short, it's always possible to convert from one loop variant to either of the other two. for-loops just give you the benefit of being able to limit the scope of a loop control variable and do any incrementation at the top. It goes without saying that in many cases one particular loop variant makes much more sense to use than the others; each has its specific use cases.

Also note that the fun doesn't just end with loops: it's also possible to convert every loop into a recursive function and vice versa (although in practice there could be limitations to this; for example a loop that worked fine could, when converted to a recursive function, produce a stack overflow error).


[I]s while/do-while in any way "distinct" from for?

It is not. For instance, the bytecode of the following two snippets is identical:

int x = 0;
while (x < 10) {
    x++;
}

and

int x = 0;
for (; x < 10;) {  // or: for (; x < 10; x++) {}
    x++;
}

both become:

   0: iconst_0      
   1: istore_1      
   2: goto          8
   5: iinc          1, 1
   8: iload_1       
   9: bipush        10
  11: if_icmplt     5
  14: return 

There was talk in the comments about for-each loops and that they might be intrinsically different from the other loop types. This is absolutely not true; for-each loops are pure syntactic sugar around iterators (or looping over arrays). Every for-each loop can also be converted to each of the other loop types. Here's an example:

for (String s : l) {  // l is a list of strings
    System.out.println(s);
}

and

String s;
Iterator<String> iter = l.iterator();  // l is a list of strings
while (iter.hasNext()) {
    s = iter.next();
    System.out.println(s);
}

both become:

  24: invokeinterface #33,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
  29: astore_3      
  30: goto          50
  33: aload_3       
  34: invokeinterface #39,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
  39: checkcast     #19                 // class java/lang/String
  42: astore_2      
  43: getstatic     #45                 // Field java/lang/System.out:Ljava/io/PrintStream;
  46: aload_2       
  47: invokevirtual #51                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
  50: aload_3       
  51: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
  56: ifne          33

Upvotes: 37

Peter Olson
Peter Olson

Reputation: 142921

The other answers have already covered the equivalence between a while loop and a for loop. That is,

while(<expr>) {
  <body>
}

is equivalent to

for(;<expr>;) {
}

Note that a similar reduction can be done with a do-while loop. Any do-while loop

do {
  <body>
} while(<expr>);

is functionally equivalent to

for (boolean firstIter = true; firstIter || <expr>; firstIter = false) {
  <body>
}

Upvotes: 2

Oleksi
Oleksi

Reputation: 13097

No, you can always rewrite a for loop as a while loop, and any while look as a for loop.

<init>
while (condition) {
...
<increment>
}

is equivalent to:

for (<init>; <condition>; <increment>) {
...
}

Upvotes: 6

Terry
Terry

Reputation: 927

"Absolutely"? I'd say no. However a test after loop aka do-while in Java would require a pretty convoluted "for" condition. Which brings one back to the boolean absolute: the condition must evaluate true or false.

So while I cannot envisage a case when the compiler could not be manipulated into performing the correct logic, I can see in very short order where anyone maintaining your program might well want you stoned (or perhaps think you were already).

On a related note there is nothing you can do in Java that cannot be done in machine language. But there are lots and lots of really good reasons for not using machine language. Most of them apply equally for when you try to get "cute" writing your code. It's all fun and games until you're on the phone with an irate customer at 0300, or your boss, or both.

Upvotes: 0

Related Questions