Skip to main content
IBM 
ShopSupportDownloads
IBM HomeProductsConsultingIndustriesNewsAbout IBM
IBM : developerWorks : Java : Education - online courses
Java Collections Framework
Download tutorial zip fileView letter-sized PDF fileView A4-sized PDF fileE-mail this tutorial to a friend
Main menuSection menuGive feedback on this tutorialPreviousNext
3. Collection interfaces and classes
  


Map interface page 7 of 8


The Map interface is not an extension of the Collection interface. Instead, the interface starts off its own interface hierarchy for maintaining key-value associations. The interface describes a mapping from keys to values, without duplicate keys, by definition.

UML Diagram for Map Interface

The interface methods can be broken down into three sets of operations: altering, querying, and providing alternative views.

The alteration operations allow you to add and remove key-value pairs from the map. Both the key and value can be null. However, you should not add a Map to itself as a key or value.

  • Object put(Object key, Object value)
  • Object remove(Object key)
  • void putAll(Map mapping)
  • void clear()

The query operations allow you to check on the contents of the map:

  • Object get(Object key)
  • boolean containsKey(Object key)
  • boolean containsValue(Object value)
  • int size()
  • boolean isEmpty()

The last set of methods allow you to work with the group of keys or values as a collection.

  • public Set keySet()
  • public Collection values()
  • public Set entrySet()

Because the collection of keys in a map must be unique, you get a Set back. Because the collection of values in a map may not be unique, you get a Collection back. The last method returns a Set of elements that implement the Map.Entry interface.

Map.Entry interface

The entrySet() method of Map returns a collection of objects that implement the Map.Entry interface. Each object in the collection is a specific key-value pair in the underlying Map.

UML Diagram for Map.Entry Interface

Iterating through this collection, you can get the key or value, as well as change the value of each entry. However, the set of entries becomes invalid, causing the iterator behavior to be undefined, if the underlying Map is modified outside the setValue() method of the Map.Entry interface.

HashMap and TreeMap classes

The Collections Framework provides two general-purpose Map implementations: HashMap and TreeMap . As with all the concrete implementations, which implementation you use depends on your specific needs. For inserting, deleting, and locating elements in a Map, the HashMap offers the best alternative. If, however, you need to traverse the keys in a sorted order, then TreeMap is your better alternative. Depending upon the size of your collection, it may be faster to add elements to a HashMap, then convert the map to a TreeMap for sorted key traversal. Using a HashMap requires that the class of key added have a well-defined hashCode() implementation. With the TreeMap implementation, elements added to the map must be sortable. We'll say more about this in Sorting.

To optimize HashMap space usage, you can tune the initial capacity and load factor. The TreeMap has no tuning options, as the tree is always balanced.

Both HashMap and TreeMap implement the Cloneable interface.

The Hashtable and Properties classes are historical implementations of the Map interface. They will be discussed in Dictionary, Hashtable, and Properties classes.

Map usage example

The following program demonstrates the use of the concrete Map classes. The program generates a frequency count of words passed from the command line. A HashMap is initially used for data storage. Afterwards, the map is converted to a TreeMap to display the key list sorted.

import java.util.*;

public class MapExample {
  public static void main(String args[]) {
    Map map = new HashMap();
    Integer ONE = new Integer(1);
    for (int i=0, n=args.length; i<n; i++) {
      String key = args[i];
      Integer frequency = (Integer)map.get(key);
      if (frequency == null) {
        frequency = ONE;
      } else {
        int value = frequency.intValue();
        frequency = new Integer(value + 1);
      }
      map.put(key, frequency);
    }
    System.out.println(map);
    Map sortedMap = new TreeMap(map);
    System.out.println(sortedMap);
  }
}

Running the program with the text from Article 3 of the Bill of Rights produces the following output. Notice how much more useful the sorted output looks.

Unsorted:

{prescribed=1, a=1, time=2, any=1, no=1, shall=1, nor=1, peace=1, owner=1, soldier=1, to=1, the=2, law=1, but=1, manner=1, without=1, house=1, in=4, by=1, consent=1, war=1, quartered=1, be=2, of=3}

and sorted:

{a=1, any=1, be=2, but=1, by=1, consent=1, house=1, in=4, law=1, manner=1, no=1, nor=1, of=3, owner=1, peace=1, prescribed=1, quartered=1, shall=1, soldier=1, the=2, time=2, to=1, war=1, without=1}

AbstractMap class

Similar to the other abstract collection implementations, the AbstractMap class overrides the equals() and hashCode() methods to ensure two equal maps return the same hash code. Two maps are equal if they are the same size, contain the same keys, and each key maps to the same value in both maps. By definition, the hash code for a map is the sum of the hash codes for the elements of the map, where each element is an implementation of the Map.Entry interface. Thus, no matter what the internal ordering of the maps, two equal maps will report the same hash code.

WeakHashMap class

A WeakHashMap is a special-purpose implementation of Map for storing only weak references to the keys. This allows for the key-value pairs of the map to be garbage collected when the key is no longer referenced outside of the WeakHashMap. Using WeakHashMap is beneficial for maintaining registry-like data structures, where the usefulness of an entry vanishes when its key is no longer reachable by any thread.

The Java 2 SDK, Standard Edition, version 1.3 adds a constructor to WeakHashMap that accepts a Map. With version 1.2 of the Java 2 platform, the available constructors permit only overriding the default load factor and initial capacity setting, not initializing the map from another map (as recommended by the Map interface documentation).


Main menuSection menuGive feedback on this tutorialPreviousNext
PrivacyLegalContact