Java in Review - Syntax Issues
(Page 2 of 9 )
When compared to languages such as C++, Java has a very simple syntax. However, there are some points of syntax that should be covered, even for the intermediate and advanced Java programmer.
Abbreviated if One of the things that is not well understood about the if statement is that it abbreviates evaluations in order from left to right. For example, consider the following code:
package oreilly.hcj.review;
public class SyntaxIssues{
public static void containsNested(final List list,
final Object target) {
Iterator iter = list.iterator();
for (Set inner = null; iter.hasNext(); inner = (Set)iter.next()) {
if (inner != null){
if (inner.contains(target)) {
// do code.
}
}
}
}
}
In this code, the method is passed a list of sets to determine whether the targeted element is in one of the nested sets. Since a list can contain nulls, the method wisely checks for null before dereferencing inner. As long as inner isn’t null, the method checks to see whether the set contains target. This code works, but the deep nesting is not necessary. You can write the code in another way:
package oreilly.hcj.review;
public class SyntaxIssues{
public static void containsNested2(final List list,
final Object target) {
Iterator iter = list.iterator();
for (Set inner = null; iter.hasNext(); inner = (Set)iter.next()) {
if ((inner != null) && (inner.contains(target))){
// do code.
}
}
}
}
In this version, the method checks for null and containment on the same line. This version of the method is in no danger of throwing NullPointerExceptions because the evaluation of the if statement is abbreviated at runtime. While evaluating an if statement, the evaluations are run from left to right. Once the evaluation reaches a definitive condition that cannot be altered by any other evaluation, the remaining evaluations are skipped.
Ternary Expressions Ternary expressions look a little strange at first. However, they can be useful in making code read better. For example, consider the following code:
package oreilly.hcj.review;
public class SyntaxIssues{
public int someMethod(final Point p) {
if (p == null) {
return 0;
} else {
return p.x + p.y;
}
}
}
Although this method runs properly, it is unnecessarily wordy. The same thing could have been accomplished using a much simpler ternary expression:
package oreilly.hcj.review;
public class SyntaxIssues {
public int someElegantMethod(final Point p) {
return p == null ? 0 : p.x + p.y;
}
}
The emphasized line is not as cryptic as it may appear at first. It is merely a large evaluation expression. If the given clause evaluates as true, then the value of the entire statement is in the -> clause. However, if the condition evaluates as false, then the value of the entire statement is in the : clause. The result of the evaluation is returned by the return statement.
Ternary statements are very useful for performing evaluations such as this. However, you have to be aware of a few gotchas. For example, the following code will not work:
p == null ? System.out.println("p is null!") : return p.x + p.y; return 0;
In this statement, the user wants to make an if-then clause that would print a message if the point passed to the method was null or return the value if the point was not null. Basically, he is going for a less wordy version of the following code:
package oreilly.hcj.review;
public class SyntaxIssues {
public static int someMethod(final Point p) {
if (p == null) {
System.out.println("p is null!")
} else {
return p.x + p.y;
}
}
return 0;
}
The problem is that a ternary expression is not an if-then clause. It is an evaluation clause. Both of the clauses in the ternary expression must evaluate to something. The statement System.out.println("p is null!") evaluates to void because the return of the println( )method is void. Additionally, the statement return p.x + p.y is pure syntactical nonsense because return is a keyword that doesn’t evaluate to anything.
Although ternary expressions are useful for shortening what would be an otherwise long and drawn-out piece of code, they can be cryptic to read if they are abused. I recommend that you use ternary expressions only for very small evaluations. If your evaluation is complex, you are better off going with the if-then structure.
Leveraging for Loops The for loop is one of the most elegant and underused looping structures in the Java language. Most developers use only the basic concept of a for loop to iterate through a predefined series of numbers:
for (int idx = 0; idx < args.length; idx++) {
// ...do something.
}
To the average reader, this code should be completely boring. However, to many developers, this is the pinnacle of for loop usage. But there are many more things that you can do with a for loop to make your code more elegant while dealing with some annoying programming issues.
Although the techniques in this section are not necessarily required, they do make your code look a lot nicer. However, if there is one concept that you should take from this section, it’s that for loops can do much more than simply cycle through numbers.
for loop fundamentals One recurring problem when dealing with collections is the need to iterate through the collection and keep track of an index at the same time. For example, you may need to copy all of thexcoordinates from aListofPointobjects into an array ofints. The following code represents a first attempt at implementing this method:
package oreilly.hcj.review;
import java.awt.Point;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class SyntaxIssues {
public static int[] extractXCoords(final List points) {
int[] results = new int[points.size()];
Point element = null;
int idx = 0;
Iterator iter = points.iterator();
while (iter.hasNext()) {
element = (Point)iter.next();
results[idx] = element.x;
idx++;
} return results;
}
}
Although this piece of code will work, it isn’t very elegant. The code would look much neater written in the following way:
package oreilly.hcj.review;
public class SyntaxIssues {
public static int[] extractXCoords2(final List points) {
int[] results = new int[points.size()];
Point element = null;
Iterator iter = points.iterator();
for (int idx = 0; iter.hasNext(); idx++) {
element = (Point)iter.next();
results[idx] = element.x;
}
return results;
}
}
This second example is much more elegant than the first. However, the important thing to note about the rewritten method is that the exit clause to the for loop has nothing to do with idx.
You can use the for loop structure in this manner because each of the statements inside the for loop are completely independent of each other. This is a fact that seems to escape many Java developers. The point is that the for loop has the following grammar:
for (Allocation Statement; Expression; Iteration Statement)
The allocation statement in the for loop is executed when the loop is set up. At each iteration of the loop, the expression in the middle is evaluated and, if the expression is true, the iteration statement is run. You can stick any statement or expression in the for loop regardless of whether they are using the same variables. For example, the following is perfectly legal:
package oreilly.hcj.review;
public class ForLoops {
public static void forWeird(){
boolean exit = false;
int idx = 0;
for (System.setProperty("user.sanity", "minimal"); exit == false;
System.out.println(System.currentTimeMillis())) {
// do some code.
idx++;
if (idx == 10) {
exit = true;
}
}
}
}
When the loop is initialized, the system property user.sanity will be set to minimal. At each iteration of the loop, the current time in milliseconds will be printed as long as exit is false. This is a great demonstration of what you can do with for loops.
Now that you know just what is possible with for loops, you can leverage them even further to do things that are a bit more mainstream.
Next: Collection iteration with for >>
More Java Articles
More By O'Reilly Media
|
This article was excerpted from chapter one of Hardcore Java, edited by Robert Simmons Jr. (O'Reilly, 2004; ISBN: 0596005687). Check it out at your favorite bookstore. Buy this book now.
|
|