Java 9 introduced several important enhancements to the Java Collections framework, including the addition of new immutable data structures. These new structures aim to improve the efficiency, safety, and simplicity of working with collections. The focus was on providing immutable versions of List, Set, and Map, which help in creating thread-safe and functional programming-friendly code. This article explores these new data structures, how they work, and how to use them effectively in your Java programs.
New Immutable Collections in Java 9
Java 9 introduced a new API for immutable collections that allows developers to create immutable instances of List, Set, and Map with a concise syntax. The main motivation behind this is to promote immutability, which is essential for thread safety and functional programming practices.
Immutable List in Java 9
The immutable List introduced in Java 9 can be created using the static methods provided in the List
interface. These lists are unmodifiable, meaning that once they are created, no modifications (such as adding or removing elements) can be performed on them.
Listlist = List.of("Java", "Python", "C++"); System.out.println(list); // Output: [Java, Python, C++] // The following will throw UnsupportedOperationException // list.add("Ruby");
Key Points:
- Immutable List created using
List.of()
- Elements cannot be added or removed after creation
- Throws
UnsupportedOperationException
for any modification attempts
Immutable Set in Java 9
Similar to the immutable List, Java 9 introduced an immutable Set via the Set.of()
method. This Set is a read-only collection, where attempts to modify it will lead to an UnsupportedOperationException
.
Setset = Set.of("Apple", "Banana", "Orange"); System.out.println(set); // Output: [Apple, Banana, Orange] // The following will throw UnsupportedOperationException // set.add("Grapes");
Key Points:
- Immutable Set created using
Set.of()
- Similar to the List, it doesn’t allow adding or removing elements after creation
Immutable Map in Java 9
Java 9 provides an immutable Map using the Map.of()
and Map.ofEntries()
methods. These methods allow developers to quickly create Maps with key-value pairs that cannot be altered after they are created.
Mapmap = Map.of(1, "Java", 2, "Python", 3, "JavaScript"); System.out.println(map); // Output: {1=Java, 2=Python, 3=JavaScript} // The following will throw UnsupportedOperationException // map.put(4, "Ruby");
Key Points:
- Immutable Map created using
Map.of()
for small Maps andMap.ofEntries()
for larger Maps - Keys and values cannot be modified once the Map is created
Benefits of Immutable Collections
The introduction of immutable collections in Java 9 provides several advantages:
- Thread Safety: Since the collection is unmodifiable, it ensures that no thread can modify it, preventing concurrency issues.
- Functional Programming: Immutability is a core concept in functional programming. These immutable collections fit well in functional programming paradigms.
- Better Performance: Immutable objects can be shared safely between threads, reducing overhead in concurrent applications.
- Ease of Use: The
List.of()
,Set.of()
, andMap.of()
methods provide a clean and concise API for creating collections.
Other Enhancements in Java 9 Collections API
In addition to immutable collections, Java 9 made several other improvements to the Collections API, such as:
- Factory Methods for Collections: Methods like
List.of()
,Set.of()
, andMap.of()
make it easier to create collections with a specific set of elements. - Stream API Enhancements: Java 9 introduced the
takeWhile()
anddropWhile()
methods to theStream
interface for more refined control over stream processing. - Improved Optional: Java 9 introduced new methods to the
Optional
class, such asifPresentOrElse()
for more flexible handling of null values.
Example: Stream Enhancements in Java 9
Listnumbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // Using takeWhile to take elements until the condition fails List result = numbers.stream() .takeWhile(n -> n < 6) .collect(Collectors.toList()); System.out.println(result); // Output: [1, 2, 3, 4, 5]
This example demonstrates how to use the takeWhile()
method to filter elements in a Stream until a condition is no longer satisfied.