【数据结构】Guava BiMap

转载:https://www.baeldung.com/guava-bimap

1. Overview

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

BiMap (or “bidirectional map”) is a special kind of a map which 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.

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

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:

1

2

3

4

5

<dependency>

    <groupId>com.google.guava</groupId>

    <artifactId>guava</artifactId>

    <version>21.0</version>

</dependency>

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:

1

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:

1

2

3

Map<String, String> capitalCountryBiMap = new HashMap<>();

//...

HashBiMap.create(capitalCountryBiMap);

  • If you are going to deal with a key of type Enum, use the create method from the class EnumHashBiMap:

1

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

1

2

3

4

BiMap<String, String> capitalCountryBiMap

  = new ImmutableBiMap.Builder<>()

    .put("New Delhi", "India")

    .build();

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:

1

2

3

4

5

6

7

8

9

10

11

12

13

@Test

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:

1

2

3

4

5

6

7

8

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

1

2

3

4

5

6

7

8

9

10

11

@Test

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.

【相同功能重写java】

public class ID {
    /**
     * String -> ID.
     */
    private HashMap<String, Integer> id;
    /**
     * ID -> String, for a better solution check Google's BiMap implementation.
     */
    private HashMap<Integer, String> di;
    private int counter = 1;

    /**
     * Constructor.
     */
    public ID() {
        id = new HashMap<String, Integer>();
        di = new HashMap<Integer, String>();
    }

    /**
     * Assigns a new ID to a string.
     *
     * @param element String.
     * @return Assigned ID.
     */
    public int set(String element) {
        Integer i = id.get(element);

        if (i == null) {
            i = counter;
            id.put(element, i);
            di.put(i, element);
            counter++;
        }
        return i;
    }

    /**
     * Get ID from String.
     *
     * @param element String.
     * @return ID for <code>element</code>.
     */
    public int getID(String element) {
        return id.get(element);
    }

    /**
     * Returns ID -> String mapping.
     *
     * @return Map ID -> String.
     */
    public HashMap<Integer, String> getHashDI() {
        return di;
    }

    /**
     * Get String from ID.
     *
     * @param id ID.
     * @return String for <code>id</code>.
     */
    public String getString(int id) {
        return di.get(id);
    }
}

猜你喜欢

转载自blog.csdn.net/liudongdong19/article/details/84349776