Saturday, November 14, 2015

Java - foreach Loop

Foreach loop is a feature that has been present in many languages like Perl, Ruby etc for some time. Java finally implemented it in Java 5. The official documents refer to this new loop as the "Enhanced for Loop", the "For-Each Loop" and the "foreach statement".

To ensure that existing code is not broken, it was decided that a new keyword will not be introduced. The changes were done in the syntax of the for keyword.

Syntax:
for (declaration : expression) {
    // Statements (generally using the variable declared above)
}

An example of usage is as follows:
public class NewFor1 {
 public static void main(String[] args) {
  int[] arr = {100, 200, 300, 400, 500};

  for (int i:arr) {
   System.out.println(i);
  }
 }
}

This code generates the following output:
$ javac NewFor1.java
$ java NewFor1
100
200
300
400
500

As you can see, the program NewFor.java is a toy program. Generally, this loop is used while iterating over a Collection.

A couple of caveats:
Caveat 1. The first part of the for loop has to be a declaration.
public class NewFor2 {
 public static void main(String[] args) {
  int i = 0;
  int[] arr = {100, 200, 300, 400, 500};

  for (i:arr) {
   System.out.println(i);
  }
 }
}

$ javac NewFor2.java 
NewFor2.java:6: error: not a statement
  for (i:arr) {
       ^
NewFor2.java:6: error: ';' expected
  for (i:arr) {
        ^
NewFor2.java:6: error: ';' expected
  for (i:arr) {
         ^
3 errors
$
This syntax makes sense because the primary purpose of this loop is to make it easy to iterate through a collection. In such a case, declaring the variable in this place makes the most sense.

Caveat 2. What does the normal for loop provide that the foreach loop does not provide?
Answer: The index. While for loop provides an index which can also be used in the statements enclosed within the loop, the index cannot be obtained directly in the foreach loop.

Make combinations of directories with one command

As you know, the command mkdir is used to create directories. However, this command has some very useful options. To create a directory called myblog, you should use the following command:
$ ls -d myblog
ls: myblog: No such file or directory
$ mkdir myblog
$ echo $?
0
Perhaps the most commonly used option is the -p option. This option has multiple uses. If a directory exists and you give a mkdir command, normally, it will throw an error as follows:
$ ls -d myblog
myblog
$ mkdir myblog
mkdir: cannot create directory `myblog': File exists
$ echo $?
1
Notice that the exit value of the command is a non-zero value.
However, if we use the -p option, then we can get the following result:
$ ls -d myblog
myblog
$ mkdir -p myblog
$ echo $?
0
As you can see, there is no error thrown in this case and the command exits with a 0 in this case. When you are writing a script and you want to ensure that a directory is present, then this command can be used to confirm the same.
This option is also used for creating a whole directory structure with one command. For example, to create a directory called myblog and a directory under it called bash and one more under it called basic_commands, you would need to do the following if you don't use the -p option:
$ mkdir myblog/ && mkdir myblog/bash && mkdir myblog/basic_commands
mkdir: cannot create directory `myblog/': File exists
$ mkdir myblog/bash && mkdir myblog/bash/basic_commands
$ echo $?
0
$
In other words, you need to know if any part of the directory structure is already present. If so, you need to avoid creating it again. Also, the creation of the subdirectories requires you to type in the full path till that point again and again. This is a hassle and is error prone too.
The -p option helps here also:
$ ls myblog
$ mkdir -p myblog/bash/basic_commands
$ echo $?
0
There is one additional trick that you may not find in your man pages. If you want to create the following directory structure:
$ ls myblog myscript
myblog:
bash  python

myscript:
bash  python
$
You would need to execute the following command:
$ mkdir -p myblog/bash myblog/python myscript/bash myscript/python
Of course, you need to be careful to avoid typos while doing this. A better way to do this is using the following command:
$ mkdir -p {myblog,myscript}/{bash,python}
A more verbose way of specifying -p is --parents:
$ mkdir --parents {myblog,myscript}/{bash,python}
Talking of verbose, to see, what is happening when you use any of the commands above, add the -v or --verbose option:
$ mkdir -v -p {myblog,myscript}/{bash,python}
mkdir: created directory `myblog'
mkdir: created directory `myblog/bash'
mkdir: created directory `myblog/python'
mkdir: created directory `myscript'
mkdir: created directory `myscript/bash'
mkdir: created directory `myscript/python'
Neat Trick!