
Before Java 9, creating immutable lists, sets, and maps required multiple lines of code using Arrays.asList()
, Collections.unmodifiableList()
, or new HashMap<>()
.
Java 9 introduced factory methods (List.of()
, Set.of()
, Map.of()
) that allow us to create immutable collections in a single line.
1. Why Use Factory Methods for Collections?
✅ Simplifies collection creation – No need for new ArrayList<>()
.
✅ Creates immutable collections – Prevents accidental modification.
✅ More readable and concise – One-liner initialization.
✅ Improves performance – No extra overhead from unmodifiableList()
.
2. Creating Immutable Collections Using List.of()
, Set.of()
, and Map.of()
Method | Purpose | Example |
---|---|---|
List.of(elements…) | Creates an immutable list | List.of("Alice", "Bob", "Charlie") |
Set.of(elements…) | Creates an immutable set | Set.of("A", "B", "C") |
Map.of(key1, value1, key2, value2…) | Creates an immutable map with up to 10 entries | Map.of("A", 1, "B", 2) |
Map.ofEntries(Map.Entry...) | Creates an immutable map with more than 10 entries | Map.ofEntries(entry("A", 1), entry("B", 2)) |
3. Examples of Factory Methods in Java 9+
📌 Example 1: Creating an Immutable List
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie");
System.out.println(names);
}
}
✅ Output:
[Alice, Bob, Charlie]
✔ No need for new ArrayList<>()
or Arrays.asList()
.
🚨 Trying to modify the list will throw an error:
names.add("David"); // ❌ UnsupportedOperationException
✅ Factory methods create immutable collections!
📌 Example 2: Creating an Immutable Set
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Integer> numbers = Set.of(10, 20, 30);
System.out.println(numbers);
}
}
✅ Output:
[10, 20, 30]
✔ No duplicates allowed!
Set.of(1, 2, 2); // ❌ Throws IllegalArgumentException (duplicate found)
✔ Immutable:
numbers.add(40); // ❌ UnsupportedOperationException
📌 Example 3: Creating an Immutable Map (Map.of()
)
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Integer> scores = Map.of(
"Alice", 90,
"Bob", 85,
"Charlie", 95
);
System.out.println(scores);
}
}
✅ Output:
{Alice=90, Bob=85, Charlie=95}
✔ Immutable:
scores.put("David", 80); // ❌ UnsupportedOperationException
🚨 Map.of()
supports only up to 10 key-value pairs.
For more than 10 entries, use Map.ofEntries()
:
import java.util.Map;
import static java.util.Map.entry;
public class Main {
public static void main(String[] args) {
Map<String, Integer> bigMap = Map.ofEntries(
entry("Alice", 90), entry("Bob", 85), entry("Charlie", 95),
entry("David", 80), entry("Eve", 88), entry("Frank", 92),
entry("Grace", 75), entry("Hank", 79), entry("Ivy", 89),
entry("Jack", 91), entry("Kate", 87)
);
System.out.println(bigMap);
}
}
✅ Output (11 entries, using Map.ofEntries()
)
{Alice=90, Bob=85, Charlie=95, David=80, Eve=88, Frank=92, Grace=75, Hank=79, Ivy=89, Jack=91, Kate=87}
4. Differences Between Java 8 and Java 9+ Collection Creation
Feature | Java 8 | Java 9+ |
---|---|---|
Immutable List | Collections.unmodifiableList(Arrays.asList("A", "B")) | List.of("A", "B") |
Immutable Set | Collections.unmodifiableSet(new HashSet<>(Arrays.asList(1, 2, 3))) | Set.of(1, 2, 3) |
Immutable Map | Collections.unmodifiableMap(new HashMap<>() {{ put("A", 1); put("B", 2); }}) | Map.of("A", 1, "B", 2) |
Allows Null Elements? | ✅ Yes | ❌ No |
Allows Duplicates? | ✅ Yes | ❌ No (Set only) |
Performance | ❌ Extra memory (wrapper collections) | ✅ Optimized, lightweight |
Lesson Reflection
- Why are
List.of()
,Set.of()
, andMap.of()
better than usingnew ArrayList<>()
? - Why do you think Java 9 factory methods do not allow
null
values? - When should you use
Map.ofEntries()
instead ofMap.of()
?
Answers to Reflection Questions on Java 9+ Collection Factory Methods
1. Why are List.of()
, Set.of()
, and Map.of()
better than using new ArrayList<>()
?
✅ They create immutable collections
- Collections created with
List.of()
,Set.of()
, andMap.of()
cannot be modified, preventing unintended changes. - This makes them safer for multi-threaded applications.
✅ They simplify collection creation
- Instead of using
new ArrayList<>()
and adding elements manually, we can initialize collections in a single line.
✅ They are more memory-efficient
- Java optimizes these immutable collections internally, making them use less memory than standard
ArrayList
orHashMap
.
✅ They remove unnecessary boilerplate code
Before Java 9 (Verbose)
List<String> list = new ArrayList<>();
list.add("Alice");
list.add("Bob");
list.add("Charlie");
Java 9+ (Simpler)
List<String> list = List.of("Alice", "Bob", "Charlie");
🚀 Less code, more readability!
2. Why do you think Java 9 factory methods do not allow null
values?
🚨 Reason 1: Avoiding NullPointerException
Issues
- Before Java 9, collections like
ArrayList
allowednull
values, which could lead to bugs when processing data. - By disallowing
null
, Java 9+ factory methods enforce better coding practices and preventNullPointerException
in future operations.
Example (Fails in Java 9+):
List<String> list = List.of("Alice", null, "Charlie"); // ❌ Throws NullPointerException
✅ Solution: Use Optional
instead of null
Optional<String> name = Optional.ofNullable(null);
🚨 Reason 2: Performance Optimization
- Allowing
null
values requires extra checks inside collections, slowing down performance. - Java 9+ removes
null
handling overhead, making these collections faster and lighter.
3. When should you use Map.ofEntries()
instead of Map.of()
?
✅ Use Map.of()
when you have 10 or fewer entries.
Map<String, Integer> scores = Map.of(
"Alice", 90, "Bob", 85, "Charlie", 95
);
🚨 Problem:
Map.of()
only supports up to 10 key-value pairs.- For 11+ entries, it throws an error.
✅ Use Map.ofEntries()
when you need more than 10 entries.
import static java.util.Map.entry;
Map<String, Integer> bigMap = Map.ofEntries(
entry("Alice", 90), entry("Bob", 85), entry("Charlie", 95),
entry("David", 80), entry("Eve", 88), entry("Frank", 92),
entry("Grace", 75), entry("Hank", 79), entry("Ivy", 89),
entry("Jack", 91), entry("Kate", 87)
);
✔ Map.ofEntries()
supports unlimited entries.
🔑 Final Thoughts
✔ Use factory methods for immutable collections (faster, safer, and less code).
✔ Java 9+ collections do not allow null
for better performance and safer code.
✔ Use Map.ofEntries()
when you have more than 10 key-value pairs.
The next feature: Compact Strings & Memory Optimization in Java 9+ 😊