How do I create a generic Set?

In another post of Java Generics you have seen how to create a generic collection using List in this example you will learn how to make a generic Set. Making a Set generic means that we want it to only hold objects of the defined type. We can declare and instantiate a generic Set like the following code.

Set<String> colors = new HashSet<>();

We use the angle brackets to define the type. We need also to define the type in the instantiation part, but using the diamond operator remove the duplicate and Java will infer the type itself. This declaration and instantiation will give you a Set object that holds a reference to String objects. If you tried to ask it to hold other type of object such as Date or Integer you will get a compiled time error.

Set<String> colors = new HashSet<>();
colors.add("Red");
colors.add("Green");
colors.add("Blue");

//colors.add(new Date()); // Compile time error!

The code for adding items to a set is look the same with the old way we code. But again, one thing you will get here for free is that the compiler will check to see if you add the correct type to the Set. If we remove the remark on the last line from the snippet above we will get a compiled time error. Because we are trying to store a Date into a Set of type String.

Now, let see how we can iterate the contents of the Set. First we’ll do it using the Iterator. And here is the code snippet.

Iterator iterator = colors.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

When using a generic Set it will know that the iterator.next() will return a type of String so that you don’t have use the cast operator. Which of course will make you code looks cleaner and more readable. We can also using the for-each loop when iterating the Set as can be seen in the following example.

for (String color : colors) {
    System.out.println(color);
}

How do I use for-each to iterate generic collections?

In this example you will learn you to iterate a generic collection using the for-each loop. There was actually no for-each keyword or statement in Java. It just a special syntax of the for loop. The structure or syntax of the for-each loop is as follows.

for (type var : collections) {
    body;
}

This form of for loop is always read as foreach and the colon (:) character is read as “in”. Given that definition, if the type is a String you will read the syntax above as “foreach String var in collections”. The var in the statement above will be given each value from the collections during the iteration process.

Let’s compare two codes, the first one that use a generic and another code that does not use a generic so we can see the difference from the iteration perspective when working with a collection.

package org.kodejava.generics;

import org.kodejava.generics.support.Customer;

import java.util.ArrayList;
import java.util.List;

public class ForEachGeneric {

    public void loopWithoutGeneric() {
        List customers = new ArrayList();
        customers.add(new Customer());
        customers.add(new Customer());
        customers.add(new Customer());

        for (int i = 0; i < customers.size(); i++) {
            Customer customer = (Customer) customers.get(i);
            System.out.println(customer.getFirstName());
        }
    }

    public void loopWithGeneric() {
        List<Customer> customers = new ArrayList<>();
        customers.add(new Customer());
        customers.add(new Customer());
        customers.add(new Customer());

        for (Customer customer : customers) {
            System.out.println(customer.getFirstName());
        }
    }
}

What you see from the code snippet above is how much more clean our code is when we are using the generic version of the collection. In the first method, the loopWithoutGeneric we have to manually cast the object back to the Customer type. But in the second method, the loopWithGeneric method, no cast is needed as the collection will return the same type as what the collection was declared to hold.

How do I create a generic collections?

In this example you will learn how to create a generic collections. Using a generic collections you can define the type of object stored in the collections. Most of the time when you are working with a collection you will store the same kind of object in it. So it is safer to work if you know what to store in the collection and what to expect when try to read some data from it without worried of creating a runtime error in your code because you place a wrong object in the collection.

Using the generic type mechanism introduced since JDK 5.0 you can declare a collections with reference to the given type. You define the type inside an angle brackets after the variable declaration and after the variable instantiation. In JDK 7.0 you can simplify this using the diamond operator. For example is you want to create a collection that stored Customer objects the declaration and instantiation code will look like the snippet below.

List<Customer> customers = new ArrayList<Customer>();

In JDK 7.0 you can write it without repeating the type on the instantiation part.

List<Customer> customers = new ArrayList<>();

Creating a collection object in this way will tell to compiler that you want to allow only to add objects of type Customer to be the content of the collection. It means the add method will take Customer as the argument and the get method will return Customer object. If you are trying to add for example Product object or Seller object the compiler will give you a compiled time error.

Let’s see a complete code snippet for this example:

package org.kodejava.generics;

import org.kodejava.generics.support.Customer;

import java.util.ArrayList;
import java.util.List;

public class GenericCollection {
    public static void main(String[] args) {
        List<Customer> customers = new ArrayList<>();
        customers.add(new Customer());
        customers.add(new Customer());

        //customers.add(new Product()); // Compile time error!

        // No cast operator required.
        Customer customer = customers.get(0);

        for (Customer cust : customers) {
            System.out.println(cust);
        }
    }
}

Another thing that you can see from the code above is that you don’t have to use cast operator anymore when obtaining data from the collection. On JDK prior to 5.0 version you will typically have to use the instanceof operator to see what type of object returned by the collection, and you have to cast it. You don’t have to do this anymore when using generic. You can also see how your code become simpler and more readable when you iterate through the contents of the collection object.

How do I use Generics in Java programming?

In this post we are going to talk about one of Java programming language feature called as generics. Generics is a feature introduced in JDK 5.0. The generics feature allow you to abstract over types. What does it mean? It means that you can create a class or method that can work for a type assigned to it. You’ll see a lot of use of generics when you are working with Java Collections. But of course generics can be used for doing other things in you program.

To illustrate this feature let us begin by creating a code when the generics are not yet available in Java to see what problem it is trying to solve.

List data = new ArrayList();
data.add("John Doe");
String name = (String) data.get(0);

Here are the things we can see from the code above. First we create an ArrayList and call it data. This variable actually can hold any Java objects in it. On the second line we add a string to this list. And finally on the third line we get the data back from the list. One thing you see here is that you need to cast the object read out from the list. Because the list doesn’t know what type to return other than java.lang.Object.

If you look to the definition of the List’s add() and get() method prior to JDK 5.0 you’ll see that the add() method will accept Object as argument and the get() method also returns Object.

Now, let say your friend try to use your class, and he tries to add another object the list. He adds the following lines.

data.add(new Date());
String name = (String) data.get(0);

This code will actually compile just fine. The add() method will work because Date extends Object. And the get() method will also compile without any error. But when we execute the program we will get a runtime error saying that it cannot cast a Date object into type of String.

Exception in thread "main" java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.String

So how do you protect your friend from making this mistake? You can use generics. You can tell what the list should store by defining the type for the list. This way you will get a compiled time check to make sure that you are adding the correct data to the list. So, your code will look like the following.

List<String> data = new ArrayList<String>();
data.add("John Doe");
String name = data.get(0);

In this generic version of the code snippet you see that now we declare the list to store an object of type String. If you tried to add a Date into the list you’ll get a compiled time error. Your IDE will mark the line as error. The other benefit is that you don’t have to do the cast anymore. Generics reduce the clutters in your code by removing the unwanted cast operator from your code.

Actually if you are working on the JDK 7, you can simplify the variable declaration using diamond operator. So you can write it like.

List<String> data = new ArrayList<>();

I hope this will give you the basic understanding of generics and how to use it in your day-to-day working with your Java projects.

How to use Preferences API to store program configurations?

The Preferences API provided in the java.util.prefs package can be used to store and retrieve application configurations. The main class is the Preferences class. Using this class you can manage the preference data such as storing, retrieving, removing and clearing the preference data.

Preferences are key-value pairs of data. You can store a string, int, boolean and other primitive data type. You can use the get() method to retrieve value associated with a key from preference node and the put() method to store a value associated with a key in the preference node. To remove a value associated with a key from preference node you can use the remove() method. And if you want to clear the keys from the preference node you can use the clear() method.

The actual storage of these preference data is dependent on the platform. For example in Windows OSes it stored in the Windows Registry. What you have to know that this Preferences API is not intended to use for storing application data, you will only use it to store configurations of your applications.

Let’s see an example of using the Preferences API.

package org.kodejava.util.prefs;

import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

public class PreferencesExample {
    public static void main(String[] args) {
        PreferencesExample demo = new PreferencesExample();
        demo.setPreferences();
    }

    private void setPreferences() {
        // Define a node to store the preference data.
        Preferences pref = Preferences.userRoot().node(getClass().getName());

        String key1 = "KEY1";
        String key2 = "KEY2";
        String key3 = "KEY3";

        // Read the value of KEY1, return an empty string if the value
        // hasn't been set previously.
        String key1Value = pref.get(key1, "");
        System.out.println("KEY1: " + key1Value);

        // Read the value of KEY2 as an integer, if the value hasn't
        // been set previously return -1.
        int key2Value = pref.getInt(key2, -1);
        System.out.println("KEY2: " + key2Value);

        // Read the value of KEY3, return true if no value was set
        // previously.
        boolean key3Value = pref.getBoolean(key3, true);
        System.out.println("KEY3: " + key3Value);

        // Set the values for all the preference key above.
        if (key1Value.equals("")) {
            pref.put(key1, "January");
        }
        if (key2Value == -1) {
            pref.putInt(key2, 1000);
        }
        if (key3Value) {
            pref.putBoolean(key3, false);
        }

        printKeys(pref);

        // Remove KEY1 from the preference data.
        pref.remove(key1);
        printKeys(pref);

        try {
            // Remove all preference data of this node.
            pref.clear();
        } catch (BackingStoreException e) {
            e.printStackTrace();
        }

        printKeys(pref);
    }

    /**
     * Print Keys in the preference node.
     * @param pref Preference node.
     */
    private void printKeys(Preferences pref) {
        System.out.println("PreferencesExample.printKeys");
        try {
            String[] keys = pref.keys();
            for (String key : keys) {
                System.out.println("Key = " + key);
            }
        } catch (BackingStoreException e) {
            e.printStackTrace();
        }
        System.out.println("============================");
    }
}

Here are the output you’ll get when running the example above:

KEY1: 
KEY2: -1
KEY3: true
PreferencesExample.printKeys
Key = KEY1
Key = KEY2
Key = KEY3
============================
PreferencesExample.printKeys
Key = KEY2
Key = KEY3
============================
PreferencesExample.printKeys
============================