Browse DevX
Sign up for e-mail newsletters from DevX


Get Familiar with J2SE 5.0 Collections

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.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

he collections API has always been one of the most important aspects of the Java Development Kit (JDK). Nearly every Java program makes use of collection classes such as HashMap, ArrayList, TreeSet and many others, each of which stores data in a variety of ways. Therefore, nearly every Java programmer must have a good understanding of how these classes work and when each is appropriate. But with the release of J2SE 5.0, everything about the way you use these classes has just changed!

The good news is that the learning curve isn't steep. J2SE 5.0 actually simplifies the collections API in many ways. All the changes introduced by J2SE 5.0 require you to create less code than previous versions of Java.

What's New for Collections in J2SE 5.0
This article focuses on new features that affect the collections API. Specifically, the features that this article covers include:

  • Generics
  • An enhanced For loop
  • Autoboxing
Each of these technologies affects the collections API. In this article, you'll see a set of downloadable sample classes that tie all three technologies together. But before digging into the new collections API features, here's a short primer on generics.

Understanding Generics
Generics are the most important feature added to the collections API. Both the enhanced for loop and autoboxing depend heavily on generics. If you're familiar with C++, in one sense, generics are Java's answer to C++ templates, but in many ways they are much more. Generics let you associate a specific type with collections. Prior to J2SE 5.0 Java collections were never directly associated with specific types, and that often caused problems. To see why, consider the following code.

import java.util.*; public class BasicCollection { public static void main(String args[]) { ArrayList list = new ArrayList(); list.add( new String("One") ); list.add( new String("Two") ); list.add( new String("Three") ); Iterator itr = list.iterator(); while( itr.hasNext() ) { String str = (String)itr.next(); System.out.println( str ); } } }

The preceding code shows how a typical collection class might look prior to J2SE 5.0. The class creates an ArrayList and adds three strings to it. Note that there's no specific type associated with this ArrayList; you can add any class that inherits from Object to the ArrayList.

Look at the while loop that retrieves the strings from the ArrayList.

while( itr.hasNext() ) { String str = (String)itr.next(); System.out.println( str ); }

The loop iterates over every item in the ArrayList. But notice what you have to do for each element retrieved—typecast each element. The typecast is required because the ArrayList does not know what types it stores. This is the problem that generics solve in Java. Generics allow you to associate a specific type with the ArrayList. So when you upgrade this BasicCollection class to use generics, the problem disappears. The GenericCollection class shown below constitutes an upgraded version

import java.util.*; public class GenericCollection { 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() ); Iterator<String> itr = list.iterator(); while( itr.hasNext() ) { String str = itr.next(); System.out.println( str ); } } }

As you can see, only a few lines change when you upgrade the class to J2SE 5.0. The first is the line of code that declares the ArrayList; this version declares the ArrayList using a type of String.

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

Notice how the code combines the type with the name of the collection. This is exactly how you specify all generics, delimiting the name of the type with angle brackets (<>), placed immediately after the end of the collection name.

Next, when declaring the Iterator, you declare it as an Iterator for the String type. You specify the generic type for the iterator exactly as you did for the ArrayList, for example:

Iterator<String> itr = list.iterator();

That line specifies the Iterator's type as String. Now, when you call the next method for the iterator, you no longer need the typecast. You can simply call the next method and get back a String type.

String str = itr.next();

Although that's a nice code-saving feature, generics does more than just save you from having to do a typecast. It will also cause the compiler to generate a compile error when you try to add an "unsupported" type to the ArrayList. What is an unsupported type? Because the ArrayList was declared to accept strings, any class that is not a String or a String subclass is an unsupported type.

The class StringBuffer is good example of an unsupported type. Because this ArrayList accepts only Strings, it will not accept a StringBuffer object. For example, it would be invalid to add the following line to the program.

list.add( new StringBuffer() );

Here's the real beauty of generics. If someone attempts to add an unsupported type to the ArrayList you won't get a runtime error; the error will be detected at compile time. You will get the following compile error.

c:\collections\GenericCollection.java:12: cannot find symbol symbol : method add(java.lang.StringBuffer) location: class java.util.ArrayList<java.lang.String> list.add( new StringBuffer() );

Catching such errors at compile time is a huge advantage for developers trying to write bug-free code. Prior to J2SE 5.0 this error would have likely shown up later as a ClassCastException at runtime. Catching errors at compile time is always preferable to waiting for the right conditions at runtime to cause the bug, because those "right conditions" may very well appear only after deployment, when your users are running the program.

Thanks for your registration, follow us on our social networks to keep up-to-date