How do I access Map element using Spring EL?

In the previous example, How do I access collections members using Spring EL?, you have seen how to access a member of a collection using Spring EL square-braces [] operator. In this post you will learn how to use the same operator to access an element of a Map object.

For demonstration we will use the same Book class in the previous example to create the bean. The class without the corresponding getters and setters is as follow:

package org.kodejava.example.spring.el;

public class Book {
    private Long id;
    private String title;
    private String author;
    private String type;

    // Getters & Setters
}

Next, let’s create the spring configuration file. In this configuration file we create a map using the <util:map> with the map id of books and add some key-value pair entries in the map.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <util:map id="books">
        <entry key="0-201-61622-X" value="The Pragmatic Programmer"/>
        <entry key="978-1-934356-56-2" value="Hello, Android"/>
        <entry key="978-1-933988-69-6" value="Secret of The JavaScript Ninja"/>
        <entry key="978-1-449-37017-6" value="Java EE 7 Essentials"/>
        <entry key="9781935182962" value="Spring Roo in Action"/>
    </util:map>

    <bean id="book1" class="org.kodejava.example.spring.el.Book"
          p:title="#{books['9781935182962']}"/>
    <bean id="book2" class="org.kodejava.example.spring.el.Book"
          p:title="#{books['978-1-933988-69-6']}"/>

</beans>

After defining the map you can see how we access an element of the map. We use the square-braces operator [], we use the same operator as we are accessing a collection member. But instead of passing the index to the operator we pass the key of the map element that we are going to read.

<bean id="book2" class="org.kodejava.example.spring.model.Book" p:title="#{books['978-1-933988-69-6']}"/>

Finally to run the configuration you’ll need to create the following class:

package org.kodejava.example.spring.el;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELMapExample {
    public static void main(String[] args) {
        ApplicationContext context =
            new ClassPathXmlApplicationContext("spel-map.xml");

        Book book1 = (Book) context.getBean("book1");
        Book book2 = (Book) context.getBean("book2");

        System.out.println("book1.getTitle() = " + book1.getTitle());
        System.out.println("book2.getTitle() = " + book2.getTitle());
    }
}

And example of output produced by this code can be seen below:

book1.getTitle() = Spring Roo in Action
book2.getTitle() = Secret of The JavaScript Ninja

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 inject collections using map element in Spring?

In this example you will see how to wire map collections. For this purpose we can use the <map> element in the Spring configuration file. This element declares the java.util.Map. We will reuse the bean that we use in the previous example How do I inject collections using list element in Spring?.

The <map> element can have many <entry> element with the key and value-ref attribute.

Here is the configuration example:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="song1" class="org.kodejava.example.spring.collection.Song">
        <property name="title" value="I Saw Her Standing There" />
        <property name="writer" value="Beatles" />
    </bean>

    <bean id="song2" class="org.kodejava.example.spring.collection.Song">
        <property name="title" value="Misery" />
        <property name="writer" value="Beatles" />
    </bean>

    <bean id="song3" class="org.kodejava.example.spring.collection.Song">
        <property name="title" value="Anna (Go to Him)" />
        <property name="writer" value="Beatles" />
    </bean>

    <bean id="publisher" class="org.kodejava.example.spring.collection.Publisher">
        <property name="name" value="EMI Studios"/>
    </bean>

    <bean id="album" class="org.kodejava.example.spring.collection.Album">
        <property name="title" value="Please Please Me"/>
        <property name="year" value="1963"/>
        <property name="publisher">
            <map>
                <entry key="publisher" value-ref="publisher"/>
            </map>
        </property>
    </bean>

</beans>

The <map> element can have many <entry> elements. We can use the key attribute to use a string as its key. If you want the key to be a reference to other bean in the Spring context you can use the key-ref instead.

The value-ref is used to set the value to refer to another bean. If the value is a simple value such as string you can use the value attribute.

To run it create the following program:

package org.kodejava.example.spring.collection;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DemoMap {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
            new String[]{"collection-map.xml"});

        Album album = (Album) context.getBean("album");
        System.out.println("Album = " + album);
    }
}

And here what you’ll get on the console:

Album = Album{title='Please Please Me', year=1963, songs=[], publisher={publisher=Publisher{name=EMI Studios}}, props={}}

How do I convert Map into JSON?

This example show you how to convert a java.util.Map into JSON string and back to Map again.

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.HashMap;
import java.util.Map;

public class MapToJson {
    public static void main(String[] args) {
        Map<String, String> colours = new HashMap<>();
        colours.put("BLACK", "#000000");
        colours.put("RED", "#FF0000");
        colours.put("GREEN", "#008000");
        colours.put("BLUE", "#0000FF");
        colours.put("YELLOW", "#FFFF00");
        colours.put("WHITE", "#FFFFFF");

        // Convert a Map into JSON string.
        Gson gson = new Gson();
        String json = gson.toJson(colours);
        System.out.println("json = " + json);

        // Convert JSON string back to Map.
        Type type = new TypeToken<Map<String, String>>(){}.getType();
        Map<String, String> map = gson.fromJson(json, type);
        for (String key : map.keySet()) {
            System.out.println("map.get = " + map.get(key));
        }
    }
}

Here is the result of the program:

json = {"RED":"#FF0000","WHITE":"#FFFFFF","BLUE":"#0000FF","BLACK":"#000000","YELLOW":"#FFFF00","GREEN":"#008000"}
map.get = #FF0000
map.get = #FFFFFF
map.get = #0000FF
map.get = #000000
map.get = #FFFF00
map.get = #008000

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 convert Properties into Map?

package org.kodejava.example.util;

import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;

public class PropertiesToMap {
    public static void main(String[] args) {
        // Create a new instance of Properties.
        Properties properties = new Properties();

        // Populate properties with a dummy application information
        properties.setProperty("app.name", "HTML Designer");
        properties.setProperty("app.version", "1.0");
        properties.setProperty("app.vendor", "HTML Designer Inc");

        // Create a new HashMap and pass an instance of Properties. Properties
        // is an implementation of a Map which keys and values stored as in a
        // String.
        Map<Object, Object> map = new HashMap<>(properties);

        // Get the entry set of the Map and print it out.
        Set propertySet = map.entrySet();
        for (Object o : propertySet) {
            Map.Entry entry = (Map.Entry) o;
            System.out.printf("%s = %s%n", entry.getKey(), entry.getValue());
        }
    }
}

How do I convert ResourceBundle to Map?

The following code snippet will convert a resource bundle into a map object, a key-value mapping. It will read from a file called Messages_en_GB.properties which corresponding to the Locale.UK. For example the file contain the following string. This file should be placed under the resources directory.

welcome.message = Hello World!
package org.kodejava.example.util;

import java.util.*;

public class ResourceBundleToMap {
    public static void main(String[] args) {
        // Load resource bundle Messages_en_GB.properties from the classpath.
        ResourceBundle resource = ResourceBundle.getBundle("Messages", Locale.UK);

        // Call the convertResourceBundleTopMap method to convert the resource
        // bundle into a Map object.
        Map<String, String> map = convertResourceBundleToMap(resource);

        // Print the entire contents of the Map.
        for (String key : map.keySet()) {
            String value = map.get(key);
            System.out.println(key + " = " + value);
        }
    }

    /**
     * Convert ResourceBundle into a Map object.
     *
     * @param resource a resource bundle to convert.
     * @return Map a map version of the resource bundle.
     */
    private static Map<String, String> convertResourceBundleToMap(ResourceBundle resource) {
        Map<String, String> map = new HashMap<>();
        Enumeration<String> keys = resource.getKeys();
        while (keys.hasMoreElements()) {
            String key = keys.nextElement();
            map.put(key, resource.getString(key));
        }
        return map;
    }
}

How do I use the HashMap class?

This examples demonstrate you how to use the HashMap class to store values in a key-value structure. In this example we store a map of error codes with their corresponding description. To store a value into the map we use the put(key, value) method and to get it back we use the get(key) method. And we can also iterate the map using the available key sets of the map.

package org.kodejava.example.util;

import java.util.HashMap;
import java.util.Map;

public class HashMapDemo {
    public static void main(String[] args) {
        Map<String, String> errors = new HashMap<>();

        // mapping some data in the map
        errors.put("404", "Resource not found");
        errors.put("403", "Access forbidden");
        errors.put("500", "General server error");

        // reading data from the map
        String errorDescription = errors.get("404");
        System.out.println("Error 404: " + errorDescription);

        // Iterating the map by the keys
        for (String key : errors.keySet()) {
            System.out.println("Error " + key + ": " + errors.get(key));
        }
    }
}

The result of the code snippet above:

Error 404: Resource not found
Error 500: General server error
Error 403: Access forbidden
Error 404: Resource not found