Iterating through the contents of a Map

Maps provide methods which let you access the keys, values, or key-value pairs of the map as collections. Iterating through the contents of a Map. You can iterate through these collections. Given the following map for example:

Map repMap = new HashMap<>();
repMap.put("Jon Skeet", 927_654);
repMap.put("BalusC", 708_826);
repMap.put("Darin Dimitrov", 715_567);

Iterating through map keys:

for (String key : repMap.keySet()) {
System.out.println(key);
}

Prints:

Darin Dimitrov
Jon Skeet
BalusC

keySet() provides the keys of the map as a Set. Set is used as the keys cannot contain duplicate values. Iterating through the set yields each key in turn. HashMaps are not ordered, so in this example the keys may be returned in
any order.

Iterating through map values:

for (Integer value : repMap.values()) {
System.out.println(value);
}

Prints:

715567
927654
708826

values() returns the values of the map as a Collection. Iterating through the collection yields each value in turn. Again, the values may be returned in any order.

Iterating through keys and values together

for (Map.Entry entry : repMap.entrySet()) {
System.out.printf("%s = %d\n", entry.getKey(), entry.getValue());
}

Prints:

Darin Dimitrov = 715567
Jon Skeet = 927654
BalusC = 708826

entrySet() returns a collection of Map.Entry objects. Map.Entry gives access to the key and value for each entry.

Merging, combine and composing Maps

Use putAll to put every member of one map into another. Keys already present in the map will have their corresponding values overwritten.

Map numbers = new HashMap<>();
numbers.put("One", 1)
numbers.put("Three", 3)
Map other_numbers = new HashMap<>();
other_numbers.put("Two", 2)
other_numbers.put("Three", 4)
numbers.putAll(other_numbers)

This yields the following mapping in numbers:

"One" -> 1
"Two" -> 2
"Three" -> 4 //old value 3 was overwritten by new value 4

If you want to combine values instead of overwriting them, you can use Map.merge, added in Java 8, which uses a user-provided BiFunction to merge values for duplicate keys. merge operates on individual keys and values, so you’ll need to use a loop or Map.forEach. Here we concatenate strings for duplicate keys:

for (Map.Entry e : other_numbers.entrySet())
numbers.merge(e.getKey(), e.getValue(), Integer::sum);
//or instead of the above loop
other_numbers.forEach((k, v) -> numbers.merge(k, v, Integer::sum));

If you want to enforce the constraint there are no duplicate keys, you can use a merge function that throws an AssertionError:

mapA.forEach((k, v) ->
     mapB.merge(k, v, (v1, v2) ->
          {throw new AssertionError("duplicate values for key: "+k);}));

Composing Map and Map to get Map

If you want to compose two mappings, you can do it as follows

Map map1 = new HashMap();
map1.put("key1", 1);
map1.put("key2", 2);
map1.put("key3", 3);
Map map2 = new HashMap();
map2.put(1, 1.0);
map2.put(2, 2.0);
map2.put(3, 3.0);
Map map3 = new new HashMap();
map1.forEach((key,value)->map3.put(key,map2.get(value)));

This yields the following mapping

"key1" -> 1.0
"key2" -> 2.0
"key3" -> 3.0

Add multiple items

We can use V put(K key,V value):

Associates the specified value with the specified key in this map (optional operation). If the map previously contained a mapping for the key, the old value is replaced by the specified value.

String currentVal;
Map map = new TreeMap<>();
currentVal = map.put(1, "First element.");
System.out.println(currentVal);// Will print null
currentVal = map.put(2, "Second element.");
System.out.println(currentVal); // Will print null yet again
currentVal = map.put(2, "This will replace 'Second element'");
System.out.println(currentVal); // will print Second element.
System.out.println(map.size()); // Will print 2 as key having
// value 2 was replaced.
Map map2 = new HashMap<>();
map2.put(2, "Element 2");
map2.put(3, "Element 3");
map.putAll(map2);
System.out.println(map.size());

Output:

3

To add many items you can use an inner classes like this:

Map map = new HashMap<>() {{
// This is now an anonymous inner class with an unnamed instance constructor
put(5, "high");
put(4, "low");
put(1, "too slow");
}};

Keep in mind that creating an anonymous inner class is not always efficient and can lead to memory leaks so when possible, use an initializer block instead:

Related Article: Maps in Java

static Map map = new HashMap<>();
static {
// Now no inner classes are created so we can avoid memory leaks
put(5, "high");
put(4, "low");
put(1, "too slow");
}

The example above makes the map static. It can also be used in a non-static context by removing all occurrences of static.

In addition to that most implementations support putAll, which can add all entries in one map to another like this:

another.putAll(one);

Creating and Initializing Maps

Introduction

Maps stores key/value pairs, where each key has an associated value. Given a particular key, the map can look up the associated value very quickly.

Maps, also known as associate array, is an object that stores the data in form of keys and values. In Java, maps are represented using Map interface which is not an extension of the collection interface.

Way 1:

/J2SE < 5.0/
Map map = new HashMap();
map.put("name", "A");
map.put("address", "Malviya-Nagar");
map.put("city", "Jaipur");
System.out.println(map);

Way 2:

/J2SE 5.0+ style (use of generics):/
Map map = new HashMap<>();
map.put("name", "A");
map.put("address", "Malviya-Nagar");
map.put("city", "Jaipur");
System.out.println(map);

Way 3:

Map map = new HashMap(){{
put("name", "A");
put("address", "Malviya-Nagar");
put("city", "Jaipur");
}};
System.out.println(map);

Way 4:

Map map = new TreeMap();
map.put("name", "A");
map.put("address", "Malviya-Nagar");
map.put("city", "Jaipur");
System.out.println(map);

Way 5:

//Java 8
final Map map =
Arrays.stream(new String[][] {
{ "name", "A" },
{ "address", "Malviya-Nagar" },
{ "city", "jaipur" },
}).collect(Collectors.toMap(m -> m[0], m -> m[1]));
System.out.println(map);

Way 6:

//This way for initial a map in outside the function
final static Map map;
static
{
map = new HashMap();
map.put("a", "b");
map.put("c", "d");
}

Way 7: Creating an immutable single key-value map.

//Immutable single key-value map
Map singletonMap = Collections.singletonMap("key", "value");

Please note, that it is impossible to modify such map.

Any attemts to modify the map will result in throwing the UnsupportedOperationException.

//Immutable single key-value pair
Map singletonMap = Collections.singletonMap("key", "value");
singletonMap.put("newKey", "newValue"); //will throw UnsupportedOperationException
singletonMap.putAll(new HashMap<>());  //will throw UnsupportedOperationException
singletonMap.remove("key");           //will throw UnsupportedOperationException
singletonMap.replace("key", "value", "newValue"); //will throw
UnsupportedOperationException
//and etc

Check if key exists

Map num = new HashMap<>();
num.put("one", "first");
if (num.containsKey("one")) {
System.out.println(num.get("one")); // => first
}

Maps can contain null values

For maps, one has to be carrefull not to confuse “containing a key” with “having a value”. For example, HashMaps can contain null which means the following is perfectly normal behavior :

Map map = new HashMap<>();
map.put("one", null);
if (map.containsKey("one")) {
System.out.println("This prints !");            // This line is reached
}
if (map.get("one") != null) {
System.out.println("This is never reached !"); // This line is never reached
}

More formally, there is no guarantee that map.contains(key) <=> map.get(key)!=null

Add an element

  1. Addition
Map map = new HashMap<>();
map.put(1, "First element.");
System.out.println(map.get(1));

Output: First element.

  1. Override
Map map = new HashMap<>();
map.put(1, "First element.");
map.put(1, "New element.");
System.out.println(map.get(1));

Output: New element.

HashMap is used as an example. Other implementations that implement the Map interface may be used as well.

Clear the map

Map map = new HashMap<>();
map.put(1, "First element.");
map.put(2, "Second element.");
map.put(3, "Third element.");
map.clear();
System.out.println(map.size()); // => 0
Use custom object as key

Before using your own object as key you must override hashCode() and equals() method of your object.

In simple case you would have something like:

class MyKey {
     private String name;
     MyKey(String name) {
         this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
          if(obj instanceof MyKey) {
              return this.name.equals(((MyKey)obj).name);
          }
          return false;
    }
    @Override
    public int hashCode() {
        return this.name.hashCode();
    }
}

hashCode will decide which hash bucket the key belongs to and equals will decide which object inside that hash bucket.

Without these method, the reference of your object will be used for above comparison which will not work unless you use the same object reference every time.

Leave a Comment