Writing Generic classes and methods Part III

Please make sure you read the part II of this article .

Writing Generic Methods
Just like generic classes, we can write generic methods that are highly general and reusable. There are also some differences when writing generic methods.

Let’s see how a non-generic method is converted to a generic one.
The following method counts number of occurrences of a String in an array of Strings:

public static int count(String[] array, String item) {
   int count = 0;

   if (item == null) {
      for (String s : array) {
         if (s == null) count++;
      }
   } else {
      for (String s : array) {
         if (item.equals(s)) {
            count++;
         }
      }
   }

   return count;

}

Here’s an example usage of this method:

String[] helloWorld = {“h”, “e”, “l”, “l”, “o”, “w”, “o”, “r”, “l”, “d”};
int count = count(helloWorld, “l”);
System.out.println(“#occurrences of l: ” + count);

Now, we need to count the occurrence of an element in an array of any type. To generify this method, replace the concrete type String with a type parameter T, hence the generic version looks like this:

 

public static <T> int count(T[] array, T item) {
   int count = 0;

   if (item == null) {
      for (T element : array) {
         if (element == null) count++;
      }
   } else {
      for (T element : array) {
         if (item.equals(element)) {
            count++;
         }
      }
   }

   return count;

}

With this generic version, we can count occurrence of a number in an array of integers like this:
Integer[] integers = {1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0};
int count = count(integers, 0);
System.out.println(“#occurrences of zeros: ” + count);
Result:

#occurrences of zeros: 8

* Using bounded type parameters in generic methods:
Like generic classes, we can use bounded type parameters to restrict the types which can be accepted by the generic method.
Let’s refactor the count() method above to work with a collection instead of an array like this:

 

public static <T> int count(Collection<T> col, T item) {
   int count = 0;

   if (item == null) {
      for (T element : col) {
         if (element == null) count++;
      }
   } else {
      for (T element : col) {
         if (item.equals(element)) {
            count++;
         }
      }
   }

   return count;

}

The following code shows how to use the bounded type parameter <T extends X> to update the method to accept only collection of sub types of Number:

public static <T extends Number> int count(Collection<T> col, T item) {
// code…
}
Here, Number is upper bound of the type parameter T. Remember the upper bound can be a class or an interface or both (the extends keyword is also used for interface here).
Testing code:

List<Integer> integers = Arrays.asList(0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1);
int count = count(integers, 1);
System.out.println(“#occurrences of 1s: ” + count);
Result:
#occurrences of 1s: 6

The following code shows the count() method now accepts only types that are sub types of JComponent (class) and Runnable (interface):
public <T extends JComponent & Runnable> int count(Collection<T> col, T item) {
}
And the following code shows how to write a generic method with two type parameters:

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: