How do I create a generic Map object?

In this examples of Java Generic you will see how to create a generic Map object. Creating a generic Map means that you can define the type of the key and the type of the value of object stored in the Map. The declaration and the instantiation of a generic Map is only different to other type of collection such as List and Set is that we to define two types. One type for the key and the other type for the value.

The syntax for creating a generic Map is as follow:

Map<K, V> map = new Map<K, V>();

Where K is the type of map key and V is the type of the value stored in the map. If you want a map to hold a value of reference to String object and using an Integer as the key, you will write the declaration and instantiation like the snippet below.

Map <Integer, String> map = new HashMap<Integer, String>();

To make it simpler, you can use the diamond operator too.

Map <Integer, String> map = new HashMap<>();

When you want to add some elements to the map you can use the same put() method. But you don’t have to worry that you put a wrong type of object into the map. Because the Java compiler will check it to see if you are storing a correct type. Generic will catch the bug that should not happen at runtime because the code is already validated at compile time.

Map <Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");

//map.put("4", new Date()); // Compile time error!  

String a = map.get(1);
String b = map.get(2);
String c = map.get(3);

The get() method will return a value from the map that correspond with the given key. Because the map know that it store values of string, it will return a string. So you don’t need to cast the return value from the map’s get() method. You might wonder why we can put keys like 1, 2, 3. Doesn’t it supposed to be type of Integer? If you remember the auto boxing feature then you’ll understand this. Behind the screen Java will convert the primitive int to Integer.

Now, after we know how to add elements and read it back from the map. Let iterate the contents of the map. A map will have two collections that you can iterate, the keys and the values. The code snippet below will demonstrate it for you. The first snippet show you how the iterate the map using the key collections while the second iterates the values of the map.

Iterate key collections.

Iterator keyIterator = map.keySet().iterator();
while (keyIterator.hasNext()) {
    Integer key = keyIterator.next();
    String value = map.get(key);
    System.out.println("key = " + key + "; value = " + value);
}

When iterating a map using the key collection you will get the key set of the map and check the hasNext() to see if it have next key. After that you can get the key using the next() method. To get the value you call the get() method and pass the key as the argument.

Iterates value collections.

Iterator valueIterator = map.values().iterator();
while(valueIterator.hasNext()) {
    System.out.println("value = " + valueIterator.next());
}

If you want to iterate the value and ignoring the keys you can get the value collections from the map. The validate if it still hold some more values you call the hasNext() method. To obtain the value simply call the next() method from the iterator.

Notice that when using generic you don’t need to do any casting when working with generic map. Everything is added to map and read from the map is according the the type of the key and the value of the map. Beside using the Iterator you can also use the for-each loop to iterate the map. Here are the version of the code above written using the for-each loop.

for (Integer key : map.keySet()) {
    String value = map.get(key);
    System.out.println("key = " + key + "; value = " + value);
}

for (String s : map.values()) {
    System.out.println("value = " + s);
}

You can choose either way that match your coding style. Both method of iterating the map object will produce the same result.

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 it self. 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 compile 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 compile 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 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 looks 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 trying to add for example Product object or Seller object the compiler will give you a compile time error.

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

package org.kodejava.example.generics;

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 convert collections into JSON?

This example show you how to convert Java collections object into JSON string. For Student class use in this example you can find it the previous example on How do I convert object into JSON?.

package org.kodejava.example.google.gson;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class CollectionToJson {
    public static void main(String[] args) {
        // Converts a collection of string object into JSON string.
        List<String> names = new ArrayList<String>();
        names.add("Alice");
        names.add("Bob");
        names.add("Carol");
        names.add("Mallory");

        Gson gson = new Gson();
        String jsonNames = gson.toJson(names);
        System.out.println("jsonNames = " + jsonNames);

        // Converts a collection Student object into JSON string
        Student a = new Student("Alice", "Apple St", getDOB(2000, 10, 1));
        Student b = new Student("Bob", "Banana St", null);
        Student c = new Student("Carol", "Grape St", getDOB(2000, 5, 21));
        Student d = new Student("Mallory", "Mango St", null);

        List<Student> students = new ArrayList<Student>();
        students.add(a);
        students.add(b);
        students.add(c);
        students.add(d);

        gson = new Gson();
        String jsonStudents = gson.toJson(students);
        System.out.println("jsonStudents = " + jsonStudents);

        // Converts JSON string into a collection of Student object.
        Type type = new TypeToken<List<Student>>() {}.getType();
        List<Student> studentList = gson.fromJson(jsonStudents, type);

        for (Student student : studentList) {
            System.out.println("student.getName() = " + student.getName());
        }
    }

    private static Date getDOB(int year, int month, int date) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DATE, date);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }
}

Here is the result of our program:

jsonNames = ["Alice","Bob","Carol","Mallory"]
jsonStudents = [{"name":"Alice","address":"Apple St","dateOfBirth":"Nov 1, 3900 12:00:00 AM"},{"name":"Bob","address":"Banana St"},{"name":"Carol","address":"Grape St","dateOfBirth":"Jun 21, 3900 12:00:00 AM"},{"name":"Mallory","address":"Mango St"}]
student.getName() = Alice
student.getName() = Bob
student.getName() = Carol
student.getName() = Mallory

Maven Dependencies

<!-- http://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.0</version>
</dependency>

How do I create type specific collections?

package org.kodejava.example.fundamental;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TypeSpecificCollection {
    public static void main(String[] args) {
        // Using a Generic can enable us to create a type specific collection
        // object. In the example below we create a Map whose key is an Integer
        // a have the value of a String.
        Map<Integer, String> grades = new HashMap<Integer, String>();
        grades.put(1, "A");
        grades.put(2, "B");
        grades.put(3, "C");
        grades.put(4, "D");
        grades.put(5, "E");

        // A value obtained from type specific collection doesn't not need to
        // be casted, it knows the type returned.
        String value = grades.get(1);
        System.out.println("value = " + value);

        // Creating a List that will contains a String only values.
        List<String> dayNames = new ArrayList<String>();
        dayNames.add("Sunday");
        dayNames.add("Monday");
        dayNames.add("Tuesday");
        dayNames.add("Wednesday");

        // We also don't need to cast the retrieved value because it knows the
        // returned type object.
        String firstDay = dayNames.get(0);
        System.out.println("firstDay = " + firstDay);
    }
}

How do I use for-each in Java?

Using for-each command to iterate arrays or a list can simplified our code. Below is an example how to do it in Java. The first loop is for iterating array and the second for iterating a list containing a some names.

package org.kodejava.example.lang;

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

public class ForEachExample {
    public static void main(String[] args) {
        Integer[] numbers = {10, 100, 1000, 10000, 100000, 1000000};

        for (Integer i : numbers) {
            System.out.println("Number: " + i);
        }

        List<String> names = new ArrayList<>();
        names.add("James");
        names.add("Joshua");
        names.add("Scott");

        for (String name : names) {
            System.out.println("Name: " + name);
        }
    }
}

The result of the code snippet:

Number: 10
Number: 100
Number: 1000
Number: 10000
Number: 100000
Number: 1000000
Name: James
Name: Joshua
Name: Scott

How do I convert Array to Collection?

package org.kodejava.example.util;

import java.util.Arrays;
import java.util.List;

public class ArrayToListExample {
    public static void main(String[] args) {
        // Creates an array of object, in this case we create an
        // Integer array.
        Integer[] numbers = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55};

        // Convert the created array above to collection, in this
        // example we convert it to a List.
        List<Integer> list = Arrays.asList(numbers);

        // We've got a list of our array here and iterate it.
        for (Integer number : list) {
            System.out.print(number + ", ");
        }
    }
}

How do I convert collection to ArrayList?

package org.kodejava.example.util;

import java.util.ArrayList;
import java.util.LinkedList;

public class CollectionToArrayList {
    public static void main(String[] args) {
        // We create LinkedList collection type at put some values
        // in it. Here we put A, B, C and D letter into it.
        LinkedList<String> linkedList = new LinkedList<String>();
        linkedList.push("A");
        linkedList.push("B");
        linkedList.push("C");
        linkedList.push("D");

        // Let say you want to convert it to other type of collection,
        // for instance here we convert it into ArrayList. To do it
        // we can pass the collection created above as a parameter to
        // ArrayList constructor.
        ArrayList<String> arrayList = new ArrayList<String>(linkedList);

        // Now we have converted the collection into ArrayList and
        // printed what is inside.
        for (String s : arrayList) {
            System.out.println("s = " + s);
        }
    }
}

How do I create an empty collection object?

Sometimes you need to return an empty collection from your Java methods. The java.util.Collections utility class have three different static constants for creating empty List, Set and Map.

  • Collections.EMPTY_LIST
  • Collections.EMPTY_SET
  • Collections.EMPTY_MAP

There are also methods when you want to create type-safe empty collections.

  • Collections.emptyList()
  • Collections.emptySet()
  • Collections.emptyMap()

Bellow it the code example.

package org.kodejava.example.util;

import java.util.*;

public class EmptyCollectionDemo {
    public static void main(String args[]) {
        List list = Collections.EMPTY_LIST;
        System.out.println("list.size()  = " + list.size());
        Set set = Collections.EMPTY_SET;
        System.out.println("set.size()   = " + set.size());
        Map map = Collections.EMPTY_MAP;
        System.out.println("map.size()   = " + map.size());

        // For the type-safe example use the following methods.
        List<String> strings = Collections.emptyList();
        System.out.println("strings.size = " + strings.size());

        Set<Long> longs = Collections.emptySet();
        System.out.println("longs.size() = " + longs.size());

        Map<String, Date> dates = Collections.emptyMap();
        System.out.println("dates.size() = " + dates.size());
    }
}

The output are:

list.size()  = 0
set.size()   = 0
map.size()   = 0
strings.size = 0
longs.size() = 0
dates.size() = 0

How do I convert a collection object into an array?

To convert collection-based object into array we can use toArray() or toArray(T[] a) method provided by the implementation of Collection interface such as java.util.ArrayList.

package org.kodejava.example.util;

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

public class CollectionToArrayExample {
    public static void main(String[] args) {
        List<String> words = new ArrayList<>();
        words.add("Kode");
        words.add("Java");
        words.add("-");
        words.add("Learn");
        words.add("Java");
        words.add("by");
        words.add("Examples");

        String[] array = words.toArray(new String[words.size()]);
        for (String word : array) {
            System.out.println(word);
        }
    }
}

Our sample code result is shown below:

Kode
Java
-
Learn
Java
by
Examples