Overview:
A Map is an object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value. The Map interface is a part of the Java Collections Framework and provides a structure for storing key-value pairs.
Supported Operations:
- Adding key-value pairs: put(K key, V value) – associates the specified value with the specified key in this map.
- Removing key-value pairs: remove(Object key) – removes the mapping for a key from this map if it is present.
- Accessing values: get(Object key) – returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
- Checking for existence: containsKey(Object key), containsValue(Object value) – checks if the map contains a specified key or value.
- Size of the map: size() – returns the number of key-value mappings in the map.
- Iterating over elements: entrySet(), keySet(), values() – provides views for iterating over entries, keys, or values.
HashMap
HashMap is a hash table-based implementation of the Map interface. It allows null values and the null key and provides constant-time performance for the basic operations (get and put), assuming the hash function disperses the elements properly among the buckets.
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
// Example using basketball player names and their jersey numbers
Map<String, Integer> basketballPlayers = new HashMap<>();
// Adding key-value pairs
basketballPlayers.put("LeBron James", 23);
basketballPlayers.put("Stephen Curry", 30);
basketballPlayers.put("Kevin Durant", 7);
// Accessing values
System.out.println("LeBron's jersey number: " + basketballPlayers.get("LeBron James")); // Output: 23
// Checking for existence
System.out.println("Contains Stephen Curry? " + basketballPlayers.containsKey("Stephen Curry")); // Output: true
// Removing key-value pairs
basketballPlayers.remove("Kevin Durant");
// Size of the map
System.out.println("Number of players: " + basketballPlayers.size()); // Output: 2
// Iterating over entries
for (Map.Entry<String, Integer> entry : basketballPlayers.entrySet()) {
System.out.println("Player: " + entry.getKey() + ", Jersey number: " + entry.getValue());
}
}
}
LinkedHashMap
LinkedHashMap is an implementation of the Map interface with predictable iteration order. It maintains a doubly linked list running through all its entries, which defines the iteration ordering, typically the order in which keys were inserted.
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapExample {
public static void main(String[] args) {
// Example using tennis player names and their rankings
Map<String, Integer> tennisPlayers = new LinkedHashMap<>();
// Adding key-value pairs
tennisPlayers.put("Roger Federer", 5);
tennisPlayers.put("Rafael Nadal", 2);
tennisPlayers.put("Novak Djokovic", 1);
// Accessing values
System.out.println("Nadal's ranking: " + tennisPlayers.get("Rafael Nadal")); // Output: 2
// Checking for existence
System.out.println("Contains Federer? " + tennisPlayers.containsKey("Roger Federer")); // Output: true
// Removing key-value pairs
tennisPlayers.remove("Novak Djokovic");
// Size of the map
System.out.println("Number of players: " + tennisPlayers.size()); // Output: 2
// Iterating over entries
for (Map.Entry<String, Integer> entry : tennisPlayers.entrySet()) {
System.out.println("Player: " + entry.getKey() + ", Ranking: " + entry.getValue());
}
}
}
TreeMap
TreeMap is a Red-Black tree-based implementation of the Map interface. It is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time.
import java.util.Map;
import java.util.TreeMap;
public class TreeMapExample {
public static void main(String[] args) {
// Example using soccer team names and their points
Map<String, Integer> soccerTeams = new TreeMap<>();
// Adding key-value pairs
soccerTeams.put("Liverpool", 82);
soccerTeams.put("Manchester City", 89);
soccerTeams.put("Chelsea", 74);
// Accessing values
System.out.println("Liverpool's points: " + soccerTeams.get("Liverpool")); // Output: 82
// Checking for existence
System.out.println("Contains Chelsea? " + soccerTeams.containsKey("Chelsea")); // Output: true
// Removing key-value pairs
soccerTeams.remove("Manchester City");
// Size of the map
System.out.println("Number of teams: " + soccerTeams.size()); // Output: 2
// Iterating over entries
for (Map.Entry<String, Integer> entry : soccerTeams.entrySet()) {
System.out.println("Team: " + entry.getKey() + ", Points: " + entry.getValue());
}
}
}
Hashtable
Hashtable is a synchronized implementation of the Map interface that does not allow null keys or values. It is a legacy class, retained for compatibility with older code.
import java.util.Hashtable;
import java.util.Map;
public class HashtableExample {
public static void main(String[] args) {
// Example using baseball player names and their home runs
Map<String, Integer> baseballPlayers = new Hashtable<>();
// Adding key-value pairs
baseballPlayers.put("Babe Ruth", 714);
baseballPlayers.put("Hank Aaron", 755);
baseballPlayers.put("Barry Bonds", 762);
// Accessing values
System.out.println("Hank Aaron's home runs: " + baseballPlayers.get("Hank Aaron")); // Output: 755
// Checking for existence
System.out.println("Contains Babe Ruth? " + baseballPlayers.containsKey("Babe Ruth")); // Output: true
// Removing key-value pairs
baseballPlayers.remove("Barry Bonds");
// Size of the map
System.out.println("Number of players: " + baseballPlayers.size()); // Output: 2
// Iterating over entries
for (Map.Entry<String, Integer> entry : baseballPlayers.entrySet()) {
System.out.println("Player: " + entry.getKey() + ", Home runs: " + entry.getValue());
}
}
}
Conclusion
The Map interface in Java provides a structure for storing key-value pairs, with various implementations catering to different requirements:
- HashMap for general-purpose use with fast operations.
- LinkedHashMap for maintaining insertion order.
- TreeMap for sorted order.
- Hashtable for thread-safe, legacy code compatibility.
By understanding the characteristics and appropriate use cases for each implementation, you can effectively manage collections of key-value pairs in your Java applications.