Concurrent Collections

by mahidhar

Concurrent collections are part of the java.util.concurrent package and are designed to handle concurrent access in a multi-threaded environment without compromising performance or consistency.

ConcurrentHashMap
Overview:
ConcurrentHashMap is a thread-safe implementation of the Map interface that allows concurrent read and write operations without locking the entire map.

code
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class ConcurrentHashMapExample {
    public static void main(String[] args) {
        // Example using Formula 1 driver names and their team names
        ConcurrentMap<String, String> f1Drivers = new ConcurrentHashMap<>();        
        // Adding key-value pairs
        f1Drivers.put("Lewis Hamilton", "Mercedes");
        f1Drivers.put("Max Verstappen", "Red Bull");
        f1Drivers.put("Charles Leclerc", "Ferrari");        
        // Accessing values
        System.out.println("Hamilton's team: " + f1Drivers.get("Lewis Hamilton")); // Output: Mercedes        
        // Removing key-value pairs
        f1Drivers.remove("Max Verstappen");        
        // Size of the map
        System.out.println("Number of drivers: " + f1Drivers.size()); // Output: 2        
        // Iterating over entries
        f1Drivers.forEach((driver, team) -> {
            System.out.println("Driver: " + driver + ", Team: " + team);
        });
    }
}

CopyOnWriteArrayList
Overview:
CopyOnWriteArrayList is a thread-safe variant of ArrayList in which all mutative operations (add, set, remove, etc.) are implemented by making a fresh copy of the underlying array.

code
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class CopyOnWriteArrayListExample {
    public static void main(String[] args) {
        // Example using Olympic athlete names
        List<String> olympicAthletes = new CopyOnWriteArrayList<>();        
        // Adding elements
        olympicAthletes.add("Usain Bolt");
        olympicAthletes.add("Michael Phelps");
        olympicAthletes.add("Simone Biles");        
        // Accessing elements
        System.out.println("First athlete: " + olympicAthletes.get(0)); // Output: Usain Bolt        
        // Removing elements
        olympicAthletes.remove("Michael Phelps");        
        // Size of the list
        System.out.println("Number of athletes: " + olympicAthletes.size()); // Output: 2        
        // Iterating over elements
        for (String athlete : olympicAthletes) {
            System.out.println("Athlete: " + athlete);
        }
    }
}

NavigableSet
Overview:
NavigableSet is a SortedSet extended with navigation methods reporting closest matches for given search targets. It provides methods like lower, floor, ceiling, and higher.

code
import java.util.NavigableSet;
import java.util.TreeSet;
public class NavigableSetExample {
    public static void main(String[] args) {
        // Example using ski jump distances
        NavigableSet<Integer> skiJumpDistances = new TreeSet<>();        
        // Adding elements
        skiJumpDistances.add(95);
        skiJumpDistances.add(100);
        skiJumpDistances.add(105);        
        // Accessing elements
        System.out.println("Closest distance <= 102: " + skiJumpDistances.floor(102)); // Output: 100
        System.out.println("Closest distance >= 102: " + skiJumpDistances.ceiling(102)); // Output: 105        
        // Removing elements
        skiJumpDistances.pollFirst(); // Removes 95        
        // Size of the navigable set
        System.out.println("Number of distances: " + skiJumpDistances.size()); // Output: 2        
        // Iterating over elements
        for (Integer distance : skiJumpDistances) {
            System.out.println("Jump distance: " + distance);
        }
    }
}

NavigableMap
Overview:
NavigableMap is a SortedMap extended with navigation methods returning the closest matches for given search targets. It provides methods like lowerEntry, floorEntry, ceilingEntry, and higherEntry.

TreeMap (as a NavigableMap)

code
public class NavigableMapExample {
    public static void main(String[] args) {
        // Example using horse race times and horse names
        NavigableMap<Integer, String> horseRaceTimes = new TreeMap<>();        
        // Adding key-value pairs
        horseRaceTimes.put(120, "Sea Biscuit");
        horseRaceTimes.put(115, "Secretariat");
        horseRaceTimes.put(118, "Man o' War");        
        // Accessing entries
        System.out.println("Closest time <= 117: " + horseRaceTimes.floorEntry(117)); // Output: 115=Secretariat
        System.out.println("Closest time >= 117: " + horseRaceTimes.ceilingEntry(117)); // Output: 118=Man o' War        
        // Removing entries
        horseRaceTimes.pollFirstEntry(); // Removes 115=Secretariat
        
        // Size of the navigable map
        System.out.println("Number of race times: " + horseRaceTimes.size()); // Output: 2        
        // Iterating over entries
        horseRaceTimes.forEach((time, horse) -> {
            System.out.println("Race time: " + time + ", Horse: " + horse);
        });
    }
}

Conclusion
Java's advanced collection types provide specialized functionality for specific use cases:

  • Concurrent Collections: Provide thread-safe operations for multi-threaded environments, with ConcurrentHashMap and CopyOnWriteArrayList being common implementations.
  • NavigableSet and NavigableMap: Extend SortedSet and SortedMap with navigation methods, with TreeSet and TreeMap as common implementations.
  • EnumSet and EnumMap: Provide highly efficient implementations for use with enum types.

Understanding these advanced collection types and their appropriate use cases can significantly improve the performance and scalability of Java applications.