Guide to the Guava BiMap – 番石榴生物图指南

最后修改: 2017年 1月 18日


1. Overview


In this tutorial, we’ll show how to use the Google Guava’s BiMap interface and its multiple implementations.

在本教程中,我们将展示如何使用Google Guava的BiMap接口及其多种实现。

A BiMap (or “bidirectional map”) is a special kind of a map that maintains an inverse view of the map while ensuring that no duplicate values are present and a value can always be used safely to get the key back.

BiMap(或 “双向地图”)是一种特殊的地图,它保持着地图的反向视图,同时确保没有重复的值,并且一个值总是可以被安全地用来取回键。

The basic implementation of BiMap is HashBiMap where internally it makes use of two Maps, one for the key to value mapping and the other for the value to key mapping.


2. Google Guava’s BiMap

2.Google Guava的BiMap

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


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

我们将首先在pom.xml中添加Google Guava库的依赖关系。


The latest version of the dependency can be checked here.


3. Creating a BiMap


You can create an instance of BiMap in multiple ways as follows:


  • If you are going to deal with a custom Java object, use the create method from the class HashBiMap:
BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
  • If we already have an existing map, you may create an instance of a BiMap using an overloaded version of the create method from a class HashBiMap:
Map<String, String> capitalCountryBiMap = new HashMap<>();
  • If you are going to deal with a key of type Enum, use the create method from the class EnumHashBiMap:
BiMap<MyEnum, String> operationStringBiMap = EnumHashBiMap.create(MyEnum.class);
  • If you intend to create an immutable map, use the ImmutableBiMap class (which follows a builder pattern):
BiMap<String, String> capitalCountryBiMap
  = new ImmutableBiMap.Builder<>()
    .put("New Delhi", "India")

4. Using the BiMap


Let’s start with a simple example showing the usage of BiMap, where we can get a key based on a value and a value based on a key:


public void givenBiMap_whenQueryByValue_shouldReturnKey() {
    BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
    capitalCountryBiMap.put("New Delhi", "India");
    capitalCountryBiMap.put("Washington, D.C.", "USA");
    capitalCountryBiMap.put("Moscow", "Russia");

    String keyFromBiMap = capitalCountryBiMap.inverse().get("Russia");
    String valueFromBiMap = capitalCountryBiMap.get("Washington, D.C.");
    assertEquals("Moscow", keyFromBiMap);
    assertEquals("USA", valueFromBiMap);

Note: the inverse method above returns the inverse view of the BiMap, which maps each of the BiMap’s values to its associated keys.


BiMap throws an IllegalArgumentException when we try to store a duplicate value twice.


Let’s see an example of the same:


@Test(expected = IllegalArgumentException.class)
public void givenBiMap_whenSameValueIsPresent_shouldThrowException() {
    BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
    capitalCountryBiMap.put("Mumbai", "India");
    capitalCountryBiMap.put("Washington, D.C.", "USA");
    capitalCountryBiMap.put("Moscow", "Russia");
    capitalCountryBiMap.put("New Delhi", "India");

If we wish to override the value already present in BiMap, we can make use of the forcePut method:


public void givenSameValueIsPresent_whenForcePut_completesSuccessfully() {
    BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
    capitalCountryBiMap.put("Mumbai", "India");
    capitalCountryBiMap.put("Washington, D.C.", "USA");
    capitalCountryBiMap.put("Moscow", "Russia");
    capitalCountryBiMap.forcePut("New Delhi", "India");

    assertEquals("USA", capitalCountryBiMap.get("Washington, D.C."));
    assertEquals("Washington, D.C.", capitalCountryBiMap.inverse().get("USA"));

5. Conclusion


In this concise tutorial, we illustrated examples of using the BiMap in the Guava library. It is predominantly used to get a key based on the value from the map.


The implementation of these examples can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as-is.