Java 9 introduced a concise way to create immutable collections using factory methods such as List.of()
, Set.of()
, and Map.of()
. Before these methods, creating even a simple list required multiple lines of boilerplate code.
These methods simplify collection creation, enforce immutability by default, and improve code readability and safety. In this article, you'll learn how to use them effectively, when to prefer them over constructors, and common mistakes to avoid.
📚 What Are Collection Factory Methods?
Factory methods in List
, Set
, and Map
are static utility methods used to quickly instantiate immutable collections with fixed content.
Example:
List<String> fruits = List.of("apple", "banana", "cherry");
This creates an immutable list containing three elements.
🧬 Syntax and Usage
List.of()
List<String> names = List.of("Alice", "Bob", "Charlie");
- Immutable
- No
null
values allowed - Fixed size
Set.of()
Set<String> colors = Set.of("red", "green", "blue");
- No duplicates
- No
null
values - Immutable
Map.of()
Map<String, Integer> ages = Map.of("John", 30, "Jane", 25);
- Accepts key-value pairs
- Throws
IllegalArgumentException
if duplicate keys are provided - Maximum of 10 entries in
Map.of()
— useMap.ofEntries()
for more
🧪 Example with Map.ofEntries()
Map<String, Integer> data = Map.ofEntries(
Map.entry("a", 1),
Map.entry("b", 2),
Map.entry("c", 3),
Map.entry("d", 4),
Map.entry("e", 5),
Map.entry("f", 6),
Map.entry("g", 7),
Map.entry("h", 8),
Map.entry("i", 9),
Map.entry("j", 10),
Map.entry("k", 11)
);
🔐 Immutability Behavior
List<String> list = List.of("A", "B");
list.add("C"); // Throws UnsupportedOperationException
- The returned collections are unmodifiable
- Ideal for use cases where immutability is desired (thread safety, defensive copies)
🚀 Performance Considerations
Feature | Traditional Constructor | Factory Method |
---|---|---|
Mutability | Mutable | Immutable |
Null Handling | Allowed | Not allowed |
Syntax Verbosity | Higher | Minimal |
Performance | Slightly less efficient | More efficient for small sets |
💡 Real-World Use Cases
- Returning read-only data from public APIs
- Creating test fixtures
- Using default or constant values
- Defensive copies in multithreaded environments
🔄 Functional Programming Support
Set<String> tags = Set.of("java", "collections", "guide");
tags.stream()
.filter(tag -> tag.length() > 4)
.forEach(System.out::println);
⚠️ Anti-Patterns and Misuse
❌ Using null
List<String> list = List.of("a", null); // Throws NullPointerException
❌ Attempting to Modify
Map<String, String> config = Map.of("env", "prod");
config.put("env", "dev"); // UnsupportedOperationException
📌 What's New in Java?
Java 8
- Introduced
Collectors.toList()
, Streams
Java 9
List.of()
,Set.of()
,Map.of()
,Map.ofEntries()
Java 10+
var
keyword with type inference
Java 21
- Sequenced collections
- Enhanced immutable data structures
✅ Best Practices
- Use factory methods when immutability is required
- Avoid mixing factory methods with mutable logic
- Use
Map.ofEntries()
for more than 10 entries - Never pass
null
to factory methods - Prefer these over
Arrays.asList()
which allowsnull
but returns fixed-size mutable list
📘 Conclusion and Key Takeaways
Java’s List.of()
, Set.of()
, and Map.of()
factory methods provide a modern, clean, and safe way to create collections.
- ✅ Less boilerplate
- ✅ Immutable by default
- ✅ Safer than mutable alternatives
- ✅ Great for functional programming and thread safety
Embrace them in all new Java code where immutability is preferred.
❓ FAQ – Java Collection Factory Methods
-
Are factory method collections thread-safe?
They're immutable, which makes them inherently safe for reads in multi-threaded scenarios. -
Can I add elements later?
No. These collections are unmodifiable. -
Can I use them with null values?
No. They throwNullPointerException
. -
What's the difference between
Arrays.asList()
andList.of()
?Arrays.asList()
returns a fixed-size list that allowsnull
.List.of()
returns a truly immutable list and disallowsnull
. -
How many entries can
Map.of()
handle?
Up to 10 key-value pairs. UseMap.ofEntries()
for more. -
Are duplicates allowed in Set.of()?
No. Duplicate elements will throw an exception. -
Can I use factory methods in Java 8?
No. They're available from Java 9 onward. -
Can I use these methods in method parameters or returns?
Absolutely. They are perfect for method-level immutability. -
Do these methods return specific classes like
ArrayList
orHashSet
?
No. They return internal, private immutable implementations. -
How do I create a mutable version from a factory collection?
Wrap it:new ArrayList<>(List.of("a", "b"))