Thursday, July 8, 2010

Playing with the For Loop in Java

Dynamic languages have emerged as a powerful force lately. This has happened for some obvious reasons. Last year when I started learning Ruby I thought that I migrated from OOPS Demo to OOPS Enterprise Edition. Everything turned out to be so flexible and so OOPS! Now if you have used Ruby or Python then you must be smiling and telling yourself “I know exactly what you mean.”

However this is not our point of discussion and you don't need to know any dynamic language to follow this tutorial.

Actually I started using this technique after using the ruby block(obj.each{|a| ...}) that lets the programmer do things effortlessly. If you know ruby then you'll understand what I mean but if you don't know then don't bother.

The whole thing comes down to how you treat the for loop. Please don't treat it as:

Magic: Every line of code that you write and that gets compiled without errors follows some logic. Back in the days when I was 12, I used to think of it as some kind of a magical thing that happens whenever we write some code and then after executing the program the computer shows the result.

For i...Next: If you have been a Visual Basic programmer all your life then please don't treat the c/c++/java for loop like

FOR i=<Lower Bound> TO <Upper Bound> STEP <Step>
….to do
NEXT


So now let us take a look at the for loop structure closely.

for( initialization ; condition ; incrementation )
{
//Code
}


If we had to write an algorithm for the above loop structure then it would look like

1. initialization
2. IF NOT condition THEN GOTO 6
3.//Code
4. incrementation
5. GOTO 2
6.


In simple English the compiler first executes initialization. Then it checks whether condition is true or not, if it evaluates to be true then the compiler executes the given code block, executes incrementation and then again sends the control back to the condition checking line.

If pay close attention you will notice that initialization and incrementation get executed. We can put in anything that we want as initialization and incrementation! So basically the following piece of code

for(int i=1;i<=10;i++)
System.out.println(i);


can be written as

for(int i=1;i<=10;System.out.println(i++));


So we punch the second line into the first one. Nice!

Here is a more practical example

Write a program to find the number of spaces in the sentence “Ralph is a good boy.”

Here is the sleek and sexy ruby code which solves the above problem.

c=0
"Ralph is a good boy.".scan(/./).each{|a| c=c+1 if a==' '}
puts c


Now here is the solution in Java

class foo 
{
public static void main(String args[])
{
int c=0;
String str="Ralph is a good boy.";
for(int i=0;i<str.length();i++)
{
if(str.charAt(i)==' ')
{
c++;
}
}
System.out.println(c);
}
}


15 lines huh? If you compare the lines of code, Ruby:Java::1:5. Now let's see what can we do to reduce the number of lines.

class foo 
{
public static void main(String args[])
{
int c=0;
for(int i=0;i<"Ralph is a good boy.".length();c=("Ralph is a good boy.".charAt(i++)==' ')? c+1 : c);
System.out.println(c);
}
}


Bingo! Straight down to 9. So the new ratio is Ruby:Java::1:3! You can use this little technique to reduce your LOC.

Cheers!

No comments:

Post a Comment