Java Collection Factory Methods – List.of, Set.of, Map.of Explained

Illustration for Java Collection Factory Methods – List.of, Set.of, Map.of Explained
By Last updated:

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() — use Map.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 allows null 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

  1. Are factory method collections thread-safe?
    They're immutable, which makes them inherently safe for reads in multi-threaded scenarios.

  2. Can I add elements later?
    No. These collections are unmodifiable.

  3. Can I use them with null values?
    No. They throw NullPointerException.

  4. What's the difference between Arrays.asList() and List.of()?
    Arrays.asList() returns a fixed-size list that allows null. List.of() returns a truly immutable list and disallows null.

  5. How many entries can Map.of() handle?
    Up to 10 key-value pairs. Use Map.ofEntries() for more.

  6. Are duplicates allowed in Set.of()?
    No. Duplicate elements will throw an exception.

  7. Can I use factory methods in Java 8?
    No. They're available from Java 9 onward.

  8. Can I use these methods in method parameters or returns?
    Absolutely. They are perfect for method-level immutability.

  9. Do these methods return specific classes like ArrayList or HashSet?
    No. They return internal, private immutable implementations.

  10. How do I create a mutable version from a factory collection?
    Wrap it: new ArrayList<>(List.of("a", "b"))