Guava -BiMap

Guava by Google contains the BiMap class which implements a bi-directional map. On many occasions I have been using a Map and had the need to invert it to use the values as keys. It is doable but somewhat cumbersome. You can always use two maps (key -> value and value -> key) but on many occasions you may run into the issue that the values are duplicated and the second map will have to deal with duplicate keys. This elegant class available in Guava may be of assistance.

Following is a screen capture from the console of the Eclipse Neon.3 (updated from Neon.2 to Neon.3 earlier today) IDE:

main <<< hashMap: {James=1111111111, John=3333333333, Melinda=4444444444, Peter=5555555555, Jane=2222222222}

main <<< name: James phone: 1111111111
main <<< name: John phone: 3333333333
main <<< name: Melinda phone: 4444444444
main <<< name: Peter phone: 5555555555
main <<< name: Jane phone: 2222222222

main <<< name: James
main <<< name: John
main <<< name: Melinda
main <<< name: Peter
main <<< name: Jane

main <<< phone: 1111111111
main <<< phone: 3333333333
main <<< phone: 4444444444
main <<< phone: 5555555555
main <<< phone: 2222222222

main <<< phone: 5555555555 corresponds to: Peter

main <<< biMap: {James=1111111111, Jane=2222222222, John=3333333333, Melinda=4444444444, Peter=5555555555}

main <<< inverseBiMap: {1111111111=James, 2222222222=Jane, 3333333333=John, 4444444444=Melinda, 5555555555=Peter}

main <<< phone: 5555555555 corresponds to: Peter
main <<< phone: 5555555555 corresponds to: Peter

In a nutshell, a HashMap is created and populated with a set of names and associated phone numbers. The contents of the HashMap are displayed. The code then iterates through the keys and then the values. Following we iterate through the entries looking for the name of the employee (i.e., Peter) associated with the specified phone number (i.e., 5555555555). This is a linear search on the HashMap.

The code then created a BiMap and populates it with the same data used by the HashMap. The contents of the BiMap and following the inverse BiMap are displayed. Finally the phone number is used to get the associated name from the inverse of the BiMap or directly from the BiMap.

The code in Java 8 follows:

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

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

/**
 * Experiment with the BiMap class.
 */
public class Solution {

	/**
	 * Test code.
	 */
	public static void main(String[] args) {

		// **** create a hash map to hold the office directory (name = phone) ****
		
		Map<String, String> hashMap = new HashMap<String, String>();
		
		// **** populate the hash map ****
		
		hashMap.put("James", "1111111111");
		hashMap.put("Jane", "2222222222");
		hashMap.put("John", "3333333333");
		hashMap.put("Melinda", "4444444444");
		hashMap.put("Peter", "5555555555");

		// **** display the hash map ****
		
		System.out.println("main <<< hashMap: " + hashMap.toString());
		System.out.println();
		
		// **** iterate through the key/value pairs ****
		
		for (Map.Entry<String, String> entry : hashMap.entrySet()) {
			System.out.println("main <<< name: " + entry.getKey() + " phone: " + entry.getValue());
		}
		System.out.println();
		
		// **** iterate through the keys (names) ****
		
		for (String name : hashMap.keySet()) {
			System.out.println("main <<< name: " + name);
		}
		System.out.println();
		
		// **** iterate through the values (phones) ****
		
		for (String phone : hashMap.values()) {
			System.out.println("main <<< phone: " + phone);
		}
		System.out.println();

		// **** SEARCH for the name associated with a specified phone number O(n) ****
		
		String phone = "5555555555";
		for (Map.Entry<String, String> entry : hashMap.entrySet()) {
			if (entry.getValue().equals(phone)) {
				System.out.println("main <<< phone: " + phone + " corresponds to: " + entry.getKey());
				break;
			}
		}
		System.out.println();
		
		// **** declare a biMap ****
		
		BiMap<String, String> biMap = HashBiMap.create();
		
		// **** populate the biMap ****
		
		biMap.put("James", "1111111111");
		biMap.put("Jane", "2222222222");
		biMap.put("John", "3333333333");
		biMap.put("Melinda", "4444444444");
		biMap.put("Peter", "5555555555");
		
		// **** display the biMap ****
		
		System.out.println("main <<< biMap: " + biMap.toString());
		System.out.println();
		
		// **** get and display the inverse of the biMap ****
		 
		BiMap<String, String> inverseBiMap = biMap.inverse();
		System.out.println("main <<< inverseBiMap: " + inverseBiMap.toString());
		System.out.println();
		
		// **** GET the name associated with a specified phone number O(1) ****

		System.out.println("main <<< phone: " + phone + " corresponds to: " + inverseBiMap.get(phone));
		System.out.println("main <<< phone: " + phone + " corresponds to: " + biMap.inverse().get(phone));
	}

}

If you have comments or questions regarding this post feel free to leave me a note. I will replay as soon as possible.

Enjoy;

John

Follow me on Twitter:  @john_canessa

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.