Java Collections.singletonMap Method
Last modified: May 1, 2025
The Collections.singletonMap
method is a useful utility in Java's
Collections framework that allows the creation of an immutable map containing
exactly one key-value pair. As part of the java.util.Collections
class, it provides a streamlined approach to handling single-entry maps without
requiring a full-fledged collection.
Singleton maps are ideal when a single-entry map is needed without modification.
They are highly memory-efficient and inherently thread-safe, making them a
reliable option in concurrent environments. Since its introduction in Java 1.3,
singletonMap
has remained a widely used tool for simplifying
map-based operations.
Overview of Collections.singletonMap
The Collections.singletonMap
method returns an immutable and
serializable map with a single key-value pair. While it implements the
Map
interface, any attempt to modify its contents—such as adding or
removing elements—results in an UnsupportedOperationException
.
Key characteristics of singletonMap
include:
- Fixed size with exactly one entry.
- Supports null values (if permitted by the value type).
- Optimized memory usage, as no additional storage is allocated.
- Thread-safe design, making it suitable for concurrent applications.
Due to its efficiency and ssimplicity, singletonMap
is commonly
used in method parameters, API calls, and scenarios where immutability is
preferred over dynamic modification.
Basic singletonMap Usage
This example demonstrates the most basic usage of Collections.singletonMap
.
We create a map with one key-value pair and demonstrate its immutability by
attempting to modify it.
package com.zetcode; import java.util.Collections; import java.util.Map; public class SingletonMapBasic { public static void main(String[] args) { // Create singleton map Map<String, Integer> ageMap = Collections.singletonMap("John", 30); // Access elements System.out.println("John's age: " + ageMap.get("John")); System.out.println("Map size: " + ageMap.size()); try { // Attempt to modify (will throw exception) ageMap.put("Alice", 25); } catch (UnsupportedOperationException e) { System.out.println("Expected exception: " + e.getMessage()); } } }
This code creates a singleton map with "John" as the key and 30 as the value. We demonstrate accessing the value and checking the map size. The attempt to add another entry throws an exception, proving immutability.
The output shows successful read operations and the expected exception when attempting modification. This behavior is fundamental to singleton collections.
Using singletonMap with Null Values
This example explores how singletonMap
handles null values. While
the key cannot be null, the value can be null if the value type permits it.
We demonstrate both cases.
package com.zetcode; import java.util.Collections; import java.util.Map; public class SingletonMapNulls { public static void main(String[] args) { // Valid: null value Map<String, String> validMap = Collections.singletonMap("config", null); System.out.println("Config value: " + validMap.get("config")); try { // Invalid: null key Map<String, String> invalidMap = Collections.singletonMap(null, "value"); } catch (NullPointerException e) { System.out.println("Expected exception: " + e.getMessage()); } } }
The example shows that while null values are permitted (when the value type
allows), null keys are prohibited. Attempting to use a null key throws a
NullPointerException
.
This behavior matches the general Map contract in Java, where keys cannot be null but values can be (unless restricted by the implementation). The output demonstrates both scenarios.
Using singletonMap in Method Parameters
The Collections.singletonMap
method provides a quick way to pass
single-entry maps to methods requiring a Map
parameter. This is
particularly useful when calling APIs or utility functions where a full-fledged
map isn't necessary. In this example, we simulate a system that retrieves
weather data for a specific city using a singleton map.
package com.zetcode; import java.util.Collections; import java.util.Map; public class SingletonMapParameter { public static void displayWeatherInfo(Map<String, Integer> weatherData) { System.out.println("Weather Report:"); weatherData.forEach((city, temp) -> System.out.println("The temperature in " + city + " is " + temp + "°C")); System.out.println("Total locations processed: " + weatherData.size()); } public static void main(String[] args) { // Using singletonMap to pass a single city's weather data displayWeatherInfo(Collections.singletonMap("Bratislava", 18)); // Alternative approach without singletonMap: // Map<String, Integer> weatherMap = new HashMap<>(); // weatherMap.put("Bratislava", 18); // displayWeatherInfo(weatherMap); } }
This example highlights how singletonMap
simplifies passing
single-value maps to methods, reducing verbosity while maintaining efficiency.
Instead of manually creating and populating a mutable map, a singleton map
provides a streamlined alternative.
Such a pattern is widely used in Java applications, particularly in API calls, configuration settings, and scenarios where only one key-value pair is required. The output demonstrates how a method can process the singleton map seamlessly.
Comparing singletonMap with Regular Map
This example compares memory usage and performance characteristics of
singletonMap
versus regular HashMap. We demonstrate the
differences in memory footprint and modification behavior.
package com.zetcode; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class SingletonMapComparison { public static void main(String[] args) { // Singleton map Map<String, String> singleton = Collections.singletonMap("id", "A100"); // Regular HashMap Map<String, String> hashMap = new HashMap<>(); hashMap.put("id", "A100"); System.out.println("Singleton map class: " + singleton.getClass()); System.out.println("HashMap class: " + hashMap.getClass()); // Memory comparison System.out.println("\nSingleton map overhead: minimal"); System.out.println("HashMap overhead: includes hash table structure"); // Modification comparison try { singleton.put("newKey", "value"); } catch (UnsupportedOperationException e) { System.out.println("\nCannot modify singleton map"); } hashMap.put("newKey", "value"); System.out.println("HashMap modified successfully"); } }
The example highlights key differences between singleton maps and regular HashMaps. Singleton maps have minimal memory overhead as they don't need hash table structures. They're immutable, while HashMaps are mutable by default.
The output shows the different behaviors and reminds us to choose the appropriate map type based on requirements. Singleton maps are perfect for immutable single-entry cases.
Using singletonMap with Custom Objects in Java
The Collections.singletonMap
method allows creating an immutable
map with a single key-value pair. This example demonstrates its behavior when
using custom objects as both keys and values, specifically with a
Person
record. We will explore how object references work within
singleton maps.
package com.zetcode; import java.util.Collections; import java.util.Map; record Person(String name) { } public class SingletonMapCustomObjects { public static void main(String[] args) { Person john = new Person("John Doe"); Person jane = new Person("Jane Smith"); Map<Person, Person> marriage = Collections.singletonMap(john, jane); System.out.println("Marriage mapping:"); marriage.forEach((k, v) -> System.out.println(k.name() + " is married to " + v.name())); // Changing the reference doesn't affect the map john = new Person("Johnny Doe"); // New object, but map remains unchanged System.out.println("\nAfter modifying original reference:"); marriage.forEach((k, v) -> System.out.println(k.name() + " is married to " + v.name())); } }
This example highlights that singletonMap
stores object references
rather than copies. Although we assign a new Person
instance to the
john
variable, the original mapping remains unchanged because
immutable collections do not update dynamically.
This behavior is consistent across all Java collections: modifying a reference does not alter objects that have already been stored within the collection.
singletonMap in Collections Framework
This example shows how singletonMap
fits within the broader
Collections framework. We'll use it alongside other collections and demonstrate
interoperability.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; public class SingletonMapInFramework { public static void main(String[] args) { // Create a list of singleton maps List<Map<String, Integer>> mapList = new ArrayList<>(); mapList.add(Collections.singletonMap("Alice", 25)); mapList.add(Collections.singletonMap("Bob", 30)); mapList.add(Collections.singletonMap("Charlie", 35)); System.out.println("List of singleton maps:"); mapList.forEach(map -> map.forEach((k, v) -> System.out.println(k + ": " + v))); // Extract all values List<Integer> ages = new ArrayList<>(); mapList.forEach(map -> ages.addAll(map.values())); System.out.println("\nAll ages: " + ages); } }
Here we see how singleton maps can be used alongside other collection types. We create a list of singleton maps, each representing a person's age. Then we extract all values into a separate list.
This demonstrates the interoperability of singleton maps with the rest of the Collections framework. The output shows the combined data from all maps in the list.
Performance Considerations
This final example examines the performance benefits of singletonMap
compared to regular maps. We'll measure memory usage and access times for both.
package com.zetcode; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class SingletonMapPerformance { public static void main(String[] args) { final int iterations = 10_000_000; // Test singleton map long startTime = System.nanoTime(); for (int i = 0; i < iterations; i++) { Map<Integer, String> map = Collections.singletonMap(i, "value"); } long singletonTime = System.nanoTime() - startTime; // Test HashMap startTime = System.nanoTime(); for (int i = 0; i < iterations; i++) { Map<Integer, String> map = new HashMap<>(); map.put(i, "value"); } long hashMapTime = System.nanoTime() - startTime; System.out.println("SingletonMap creation time: " + (singletonTime / 1_000_000) + " ms"); System.out.println("HashMap creation time: " + (hashMapTime / 1_000_000) + " ms"); System.out.println("Ratio: " + ((double)hashMapTime / singletonTime)); } }
The performance test shows that singletonMap
is significantly
faster for creation than HashMap when you only need one entry. It also uses
less memory as it doesn't allocate a hash table.
The output demonstrates the time difference in creating millions of each map type. Singleton maps are optimal for single-entry cases where immutability is acceptable.
Source
Java Collections.singletonMap Documentation
In this article, we've explored the Java Collections.singletonMap
method in depth. We've covered basic usage, null handling, practical applications,
performance, and integration with other collections.
Author
List all Java tutorials.