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.
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.
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.
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)
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.