Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Get Familiar with J2SE 5.0 Collections : Page 2

Although you may be completely at ease with Java collections in previous versions, J2SE 5.0 collections are both simpler and different, requiring less code—but altered programming techniques.


advertisement
Using the Enhanced For Loop
A for each looping construct is something that Java lacked for some time. Other languages such as Visual Basic and C# provide that construct, allowing programmers to loop over all of the contents of a collection easily. A for each loop gives you the ability to access the contents of a collection without the need for an iterator. Now (finally) Java has a for each looping construct, in the form of the enhanced for loop.

The enhanced for loop was one of the most anticipated features of J2SE 5.0. The feature lets you simplify the code you've seen so far even further by eliminating the Iterator altogether. Here's a version upgraded to use the enhanced for loop.

import java.util.*; public class EnhancedForCollection { public static void main(String args[]) { ArrayList<String> list = new ArrayList<String>(); list.add( new String("One") ); list.add( new String("Two") ); list.add( new String("Three") ); //list.add( new StringBuffer() ); for( String str : list ) { System.out.println( str ); } } }

The preceding code eliminates the Iterator and while loop completely, leaving just these three lines of code.

for( String str : list ) { System.out.println( str ); }

The format for the enhanced for loop is as follows.



for( [collection item type] [item access variable] : [collection to be iterated] )

The first parameter, the collection item type, must be a Java type that corresponds to the generic type specified when the collection was created. Because this collection is type ArrayList , the collection item type is String.

The next parameter provided to the enhanced for loop is the name of the access variable, which holds the value of each collection item as the loop iterates through the collection. That variable must also be the same as that specified for the collection item type.

For the last parameter, specify the collection to be iterated over. This variable must be declared as a collection type, and it must have a generic type that matches the collection item type. If these two conditions are not met, a compile error will result.

Primitive Data Types and Autoboxing
One more feature of considerable importance was added to the J2SE 5.0 implementation—the ability to automatically box and unbox primitive data types. This greatly reduces the complexity normally associated with the code used to add and access primitive data types in the collections API.

If you're wondering what boxing and unboxing are, you must first look at how Java handled primitive data types prior to J2SE 5.0. Here's a simple Java application that makes use of primitive data types with the collections API, prior to J2SE 5.0.

import java.util.*; public class PrimitiveCollection { public static void main(String args[]) { ArrayList list = new ArrayList(); // box up each integer as they are added list.add( new Integer(1) ); list.add( new Integer(2) ); list.add( new Integer(3) ); //list.add( new StringBuffer() ); // now iterate over the collection and unbox Iterator itr = list.iterator(); while( itr.hasNext() ) { Integer iObj = (Integer)itr.next(); int iPrimitive = iObj.intValue(); System.out.println( iPrimitive ); } } }

The preceding code illustrates two distinct steps that had to occur when using primitives with the collections API. Because the collection types hold Objects rather than primitive types, you had to box primitive item types into a suitable wrapper object. For example, the preceding code boxes the int primitive data type into an Integer object using the following lines of code:

list.add( new Integer(1) ); list.add( new Integer(2) ); list.add( new Integer(3) );

But the boxing requirement presents a problem when later code tries to access the primitive int variables stored in the collection. Because the primitive data types were stored as Integer objects they will be returned from the collection as Integer objects, not as int variables, forcing yet another conversion to reverse the boxing process:

Iterator itr = list.iterator(); while( itr.hasNext() ) { Integer iObj = (Integer)itr.next(); int iPrimitive = iObj.intValue(); System.out.println( iPrimitive ); }

In this case, the code first retrieves each item as an Integer object, named iObj. Next, it converts the Integer object into an int primitive by calling its intValue method.

Primitive Data Types and Autoboxing (continued)
Using autoboxing, storing primitive types in collections and retrieving them becomes far simpler. Here's an example.

import java.util.*; public class AutoBoxCollection { public static void main(String args[]) { ArrayList<Integer> list = new ArrayList<Integer>(); // box up each integer as it's added list.add( 1 ); list.add( 2 ); list.add( 3 ); //list.add( new StringBuffer() ); // now iterate over the collection for( int iPrimitive: list ) { System.out.println( iPrimitive ); } } }

This autoboxing example begins by creating an ArrayList with the generic type of Integer.

ArrayList<Integer> list = new ArrayList<Integer>();

After creating the list with the wrapper type of Integer, you can add primitive ints to the list directly.

list.add( 1 ); list.add( 2 ); list.add( 3 );

Now, you no longer need to wrap each integer in an Integer object. In addition, accessing the individual list members is also considerably easier.

for( int iPrimitive: list ) { System.out.println( iPrimitive ); }

The preceding example shows how you can use the enhanced for loop to iterate over a collection of primitive data types: in this case, retrieving each primitive variable directly as an int with no type conversion required. In other words, autoboxing and unboxing let you use primitive data types with collections as easily as objects.

The addition of generics to J2SE 5.0 give you the ability to specify exactly what type of data a collection can store. That, in turn, enables the compiler to ensure that the collection accepts only the correct type of object and eliminates the need to typecast items stored to or retrieved from the collection.

Generics also allow you to use the enhanced for loop, which provides the same functionality as the for each construct found in many other programming languages. This enhanced for loop" eliminates the need for iterators and greatly simplifies the process of iterating through a collection of items.

Finally, adding primitive data types to collections has always been a tedious process. Developers have had to box primitive types such as int into Integer objects and later unbox them back into int primitive types. Autoboxing and unboxing allows Java to handle this overhead for you, resulting in much clearer source code when using collections with primitive data types.

These changes necessarily alter the techniques you use to access collection data in J2SE 5.0—greatly simplifying Java code used to access the collections API.



Jeff Heaton is an author, college instructor, and consultant. Jeff is the author of four books and over two dozen journal and magazine articles. Jeff maintains a personal website where he publishes information about artificial intelligence, spider/bot programming, and other topics.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap