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 follows:

package org.kodejava.spring.core.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.spring.core.el.Book" p:title="#{books['9781935182962']}" />
    <bean id="book2" class="org.kodejava.spring.core.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.spring.core.el.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.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELMapExample {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext 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

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I create a generic Map object?

In this example of Java Generics 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 follows:

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 has 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. To validate if it still holds more entries 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 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.spring.core.Song">
        <property name="title" value="I Saw Her Standing There" />
        <property name="writer" value="Beatles" />
    </bean>

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

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

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

    <bean id="album" class="org.kodejava.spring.core.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 creates the following program:

package org.kodejava.spring.core;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DemoMap {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("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={}}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

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.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

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.11.0</version>
</dependency>

Maven Central

How do I convert Properties into Map?

package org.kodejava.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<Map.Entry<Object, Object>> propertySet = map.entrySet();
        for (Map.Entry<Object, Object> entry : propertySet) {
            System.out.printf("%s = %s%n", entry.getKey(), entry.getValue());
        }
    }
}

The output of the code snippet above:

app.vendor = HTML Designer Inc
app.name = HTML Designer
app.version = 1.0