HashMap in Java is Hash table based implementation of the Map interface that is used for storing (key, value) pairs. HashMap class in Java extends AbstractMap class and implements Map, Cloneable and Serializable interfaces.
Some of the important points about HashMap are-
- HashMap is an unordered collection which means HashMap does not guarantee the order of its elements.
- HashMap in Java permits multiple null values and a single null key.
- Key in the HashMap should be unique otherwise the previous stored value for the same key will be overwritten. Duplicate values are allowed though.
- HashMap works on the concept of hashing and the key is used to calculate the hash code. This hash code decides where will be the (key, value) pair stored.
- HashMap in Java is not synchronized so it is not thread safe. If HashMap is accessed concurrently by multiple threads and at least one of the threads modifies the map structurally, then the HashMap must be synchronized externally.
- HashMap does not implement Iterable interface so HashMap by itself can’t be iterated. You can get the “Collection view” of the Map though and iterate it.
Java HashMap constructors
HashMap class in Java has four constructors-
- HashMap()- This constructor creates an empty HashMap with the default initial capacity (16) and the default load factor (0.75).
- HashMap(int initialCapacity)- This constructor creates an empty HashMap with the specified initial capacity and the default load factor (0.75). If you want a HashMap with a bigger initial capacity you can use this constructor.
- HashMap(int initialCapacity, float loadFactor)- This constructor creates an empty HashMap with the specified initial capacity and load factor.
- HashMap(Map<? extends K,? extends V> m)- Constructs a new HashMap with the same mappings as the specified Map.
Java HashMap creation example
Here is a simple Java example creating a HashMap and storing (key, value) pairs to it. We’ll also get the collection view of the Map using the entrySet method and use that to iterate the created HashMap.
public class HashMapSorting { public static void main(String[] args) { // creating HashMap Map<String, String> langMap = new HashMap<String, String>(); // Storing (key, value) pair to HashMap langMap.put("ENG", "English"); langMap.put("NLD", "Dutch"); langMap.put("ZHO", "Chinese"); langMap.put("BEN", "Bengali"); langMap.put("ZUL", "Zulu"); // retrieving value using key String language = langMap.get("BEN"); System.out.println("Language- " + language); System.out.println("-- Map Elements --"); for(Map.Entry<String, String> lang : langMap.entrySet()) { System.out.println("Key- " + lang.getKey() + " Value- " + lang.getValue()); } } }
Output
Language- Bengali -- Map Elements -- Key- ZHO Value- Chinese Key- ZUL Value- Zulu Key- NLD Value- Dutch Key- BEN Value- Bengali Key- ENG Value- English
As you can see in the code a HashMap is created using the default constructor and the elements added to it using the put() method. Value mapped to any specific key can be retrieved by passing the key in the get() method.
From the displayed elements of the HashMap you can also see that the order is not maintained.
Initial capacity and load factor in HashMap
HashMap has two parameters that affect its performance:
- Initial capacity
- Load factor
The capacity is the number of buckets in the hash table. Initial capacity is simply the capacity at the time the hash table is created.
HashMap internally uses an array for storing its elements and each array of index is known as one bucket. By default an array has 16 buckets. For every (key, value) pair added to HashMap a hashcode is calculated using the key. That hashcode decides element goes to which bucket.
The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased. When the number of entries in the hash table exceeds the product of the load factor and the current capacity, the hash table is rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets. Default load factor is 0.75
- Refer How HashMap Internally Works in Java to know more about the internal implementation of HashMap in Java.
Methods in Java HashMap class
Some of the important methods in the HashMap class are listed below.
- clear()- Removes all of the mappings from this map.
- computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)- If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.
- computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)- If the value for the specified key is present and non-null, attempts to compute a new mapping given the key and its current mapped value.
- containsKey(Object key)- Returns true if this map contains a mapping for the specified key.
- containsValue(Object value)- Returns true if this map maps one or more keys to the specified value.
- entrySet()- Returns a Set view of the mappings contained in this map.
- get(Object key)- Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
- isEmpty()- Returns true if this map contains no key-value mappings.
- keySet()- Returns a Set view of the keys contained in this map.
- put(K key, V value)- Associates the specified value with the specified key in this map.
- putIfAbsent(K key, V value)- If the specified key is not already associated with a value (or is mapped to null) associates it with the given value and returns null, else returns the current value.
- remove(Object key)- Removes the mapping for the specified key from this map if present.
- remove(Object key, Object value)- Removes the entry for the specified key only if it is currently mapped to the specified value.
- replace(K key, V value)- Replaces the entry for the specified key only if it is currently mapped to some value.
- size()- Returns the number of key-value mappings in this map.
HashMap allows null as key and value
HashMap in Java allows one null key and multiple null values.
public class HashMapSorting { public static void main(String[] args) { // creating HashMap Map<String, String> langMap = new HashMap<String, String>(); // Storing (key, value) pair to HashMap langMap.put("ENG", "English"); langMap.put("NLD", null); langMap.put("ZHO", null); langMap.put("BEN", "Bengali"); langMap.put("ZUL", "Zulu"); langMap.put(null, "French"); langMap.put(null, "Hindi"); System.out.println("-- Map Elements --"); for(Map.Entry<String, String> lang : langMap.entrySet()) { System.out.println("Key- " + lang.getKey() + " Value- " + lang.getValue()); } } }
Output
-- Map Elements -- Key- ZHO Value- null Key- ZUL Value- Zulu Key- null Value- Hindi Key- NLD Value- null Key- BEN Value- Bengali Key- ENG Value- English
As you can see null is inserted twice as a key but only one null key is stored. For value null can be passed multiple times.
Java HashMap iteration
HashMap by itself can’t be iterated. You can get the “Collection view” of the Map though and iterate it for example keySet() method returns a set view of the keys in the Map which can then be iterated.
- Refer How to Loop Through a Map in Java to see different options for iterating a HashMap in Java.
The iterators returned by all of HashMap's "collection view methods" are fail-fast: if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException.
Example code
In the example we’ll get the Set view of the mapped entries using the entrySet() method. While iterating that Set we’ll try to remove an element from the HashMap which means a structural modification.
public class HashMapSorting { public static void main(String[] args) { // creating HashMap Map<String, String> langMap = new HashMap<String, String>(); // Storing (key, value) pair to HashMap langMap.put("ENG", "English"); langMap.put("NLD", "Dutch"); langMap.put("ZHO", "Chinese"); langMap.put("BEN", "Bengali"); langMap.put("ZUL", "Zulu"); langMap.put("FRE", "French"); Set<Map.Entry<String, String>> langSet = langMap.entrySet(); Iterator<Map.Entry<String, String>> itr = langSet.iterator(); while (itr.hasNext()) { Map.Entry<String, String> entry = itr.next(); System.out.println("Key is " + entry.getKey() + " Value is " + entry.getValue()); // removing value using HashMap's remove method if(entry.getKey().equals("NLD")){ langMap.remove(entry.getKey()); } } } }
Output
Key is ZHO Value is Chinese Key is ZUL Value is Zulu Key is NLD Value is Dutch Exception in thread "main" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429) at java.util.HashMap$EntryIterator.next(HashMap.java:1463) at java.util.HashMap$EntryIterator.next(HashMap.java:1461) at org.netjs.examples.HashMapSorting.main(HashMapSorting.java:31)
Since Map is structurally modified while iteration is going on so the ConcurrentModificationException is thrown.
HashMap is not synchronized
HashMap in Java is not synchronized. If HashMap is accessed concurrently by multiple threads and at least one of the threads modifies the map structurally, then the HashMap must be synchronized externally. In order to synchronize Map you can use Collections.synchronizedMap() method which returns a synchronized Map backed by the specified map.
As example –
Map<String, String> m = Collections.synchronizedMap(new HashMap(...));
That's all for this topic HashMap in Java With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!
Related Topics
You may also like-
No comments:
Post a Comment