However, collection classes such as ArrayList can take any object. But what do we do when we want to have only Strings in a collection. How do you ensure no other type is inserted? Consider the following code in J2SE 1.4.
// program to convert all strings to uppercase and display Iterator itr = al.iterator(); String st; while ( itr.hasNext()) { st = (String) itr.next(); // works provided object in the collection is of type String System.out.println( st.toUpperCase()); }The above program fails if an object in the ArrayList of type other than String.
The solution to the problem is to inform the compiler what type of objects we want to have in a collection and let compiler check for appropriate type.
The following code shows how we can inform to compiler about the type of object a collection should support.
void displayUpper( Collection c) { Iterator itr = c.iterator(); while ( itr.hasNext()) System.out.println( itr.next().toUpperCase()); }The above code needs no type casting because compiler knows that we have only String objects in the collection. It provides compile-time type checking.
Generic are not similar to templates of C++. Java doesn't write another class (like it is in C++) with the specified data type. So no code-size increase will take place. Generics simply provide compile-time type safety and eliminate the need for casts.
In J2SE 1.4, iterating over a collection is lengthy. We have to get an iterator and then use methods like hasNext() and next() to get each object of the collection.
The following is the code to take each element of the collection in J2SE 1.4.
void display( Collection c) { Iterator itr = c.iterator(); while ( itr.hasNext()) System.out.println( itr.next() ); }
void display( Collection c) { for ( Object obj : c ) System.out.println( obj ); }For each object in collection c the loop is executed by copying the object into obj. As J2SE 1.5 supports generics, for loop can make use of generics as follows:
void display( Collection c) { for (String s : c ) System.out.println( s.toUpperCase() ); }The above code makes use of new for loop to eliminate Iterator and Generic to avoid type casting. What's more about new for loop is that it works even with arrays.
int a[] = {10,20,30}; for ( int i : a ) System.out.println( i );The following function takes an array of strings and returns a single concatenated string.
String concatenate(String st[]) { String cs = ""; for ( String s : st ) cs += s; return cs; }
int n[]= {10,20,30}; ArrayList al = new ArrayList(); for ( int i=0; i < n.length ; i ++) al.add ( new Integer( n[i]) ); // explicit boxingWhenever we have to use a standard data type where an object is expected, we have to convert standard type to object using wrapper class. It could be pain if it is to be done many times. Also you have to convert objects back to standard type (unbox) to process the data.
The following code demonstrates explicit unboxing.
Iterator itr = al.iterator(); Integer obj; int sum =0; while( itr.hasNext()) { obj = (Integer) itr.next(); sum += obj.intValue(); // explicit unboxing }Boxing and Unboxing are automatic in J2SE 1.5. So, no need to explicitly convert the standard types to objects and objects back to standard data types. Just specify the type of the collection then compiler takes care of automatically convert standard type to object and back to standard type.
The following is the code in J2SE 1.5 for the same program given above.
int n[]= {10,20,30}; ArrayList al = new ArrayList(); for ( int i=0; i < n.length ; i ++) al.add ( n[i] ); // automatic boxing // process data int sum =0; for ( Integer i : al) { sum += i; // automatic unboxing }
In J2SE 1.4 or before we had to refer to each static member explicity using the class name. But in Tiger, once you import static members of the class then static members can be accessed directly.
import static java.lang.Math.*; public class Test { public static void main(String args[]) {int n = -20; System.out.println( abs(n)); // earlier it was Math.abs(n) } }
The following function takes variable number of arguments and returns the sum of the given numbers. The parameter values is of type int[].
int sum(int ... values) { int s = 0; for ( int e : values) s += e; return s; }
The following example show how to create an enumeration.
enum Season { WINTER, SPRING, SUMMER, FALL }You can also take all values of the enumeration using a for each loop and use it switch statement.
enum Week { MON,TUE,WED,THU,FRI,SAT,SUN } for (Week w : Week.values()) // do something with wThe following program displays the week and wage to be paid for that week.
enum Week { MON,TUE,WED,THU,FRI,SAT,SUN } class Test { public static void main(String args[]) { for ( Week w : Week.values()) System.out.println( w + " : " + getWage(w)); } public static int getWage(Week w) { switch(w) { case MON : return 120; case TUE : case WED : return 100; case THU : case FRI : return 90; case SAT : return 130; case SUN : return 150; } } } // end of class