1. Overview

A ClassToInstanceMap<B> is a special kind of map that associates classes with corresponding instances. It makes sure that all the keys and the values are subtypes of the upper bound type B.

ClassToInstanceMap extends Java’s Map interface and provides two additional methods: T getInstance(Class<T>) and T putInstance(Class<T>, T). The advantage of this map is that these two methods can be used to perform type-safe operations and avoid casting.

In this tutorial, we will show how to use the Google Guava’s ClassToInstanceMap interface and its implementations.

2. Google Guava’s ClassToInstanceMap

Let’s have a look at how to use the implementation.

We’ll start by adding the Google Guava library dependency in the pom.xml:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>21.0</version>
</dependency>

The latest version of the dependency can be checked here.

ClassToInstanceMap interface has two implementations: a mutable and an immutable one. Let’s have a look at each of them separately.

3. Creating an ImmutableClassToInstanceMap

We can create an instance of ImmutableClassToInstanceMap in a number of ways:

  • using the of() method to create an empty map:
    ImmutableClassToInstanceMap.of()
  • using the of(Class<T> type, T value) method to create a single entry map:
    ImmutableClassToInstanceMap.of(Save.class, new Save());
  • using copyOf() method which accepts another map as a parameter. It will create a map with the same entries as map provided as the parameter:
    ImmutableClassToInstanceMap.copyOf(someMap)
  • using the builder:
    ImmutableClassToInstanceMap.<Action>builder()
      .put(Save.class, new Save())
      .put(Open.class, new Open())
      .put(Delete.class, new Delete())
      .build();

4. Creating a MutableClassToInstanceMap

We can also create an instance of MutableClassToInstanceMap:

  • using the create() method which makes an instance backed by HashMap:
    MutableClassToInstanceMap.create();
  • using the create(Map<Class<? extends B>, B> backingMap) which makes an instance backed by the provided empty map:
    MutableClassToInstanceMap.create(new HashMap());

5. Usage

Let’s have a look how to use the two new methods that are added to the regular Map interface:

  • first method is <T extends B> T getInstance(Class<T> type):
    Action openAction = map.get(Open.class);
    Delete deleteAction = map.getInstance(Delete.class);
  • second method is <T extends B> T putInstance(Class<T> type, @Nullable T value):
    Action newOpen = map.put(Open.class, new Open());
    Delete newDelete = map.putInstance(Delete.class, new Delete());

6. Conclusion

In this quick tutorial, we showed examples how to use ClassToInstanceMap from the Guava library.

The implementation of these examples can be found in these examples can be found in the GitHub project.