In Java, you can use the Stream API’s Collectors to gather stream results into an immutable collection. Since Java 10, you can use Collectors.toUnmodifiableList(), Collectors.toUnmodifiableSet(), and other similar methods to collect the results into unmodifiable collections.
Here’s how you can collect the stream results into an immutable collection:
1. Immutable List
To collect the results of a stream into an immutable list:
package org.kodejava.util.stream;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ImmutableCollectionExample {
public static void main(String[] args) {
List<String> immutableList = Stream.of("apple", "banana", "cherry")
.collect(Collectors.toUnmodifiableList());
System.out.println(immutableList);
// Attempting to modify the list will throw UnsupportedOperationException
// immutableList.add("date"); // Throws UnsupportedOperationException
}
}
2. Immutable Set
To collect the results into an immutable set:
package org.kodejava.util.stream;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ImmutableCollectionExample {
public static void main(String[] args) {
Set<String> immutableSet = Stream.of("apple", "banana", "cherry")
.collect(Collectors.toUnmodifiableSet());
System.out.println(immutableSet);
// Attempting to modify the set will throw UnsupportedOperationException
// immutableSet.add("date"); // Throws UnsupportedOperationException
}
}
3. Immutable Map
To collect results into an immutable map:
package org.kodejava.util.stream;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ImmutableCollectionExample {
public static void main(String[] args) {
Map<String, Integer> immutableMap = Stream.of("apple", "banana", "cherry")
.collect(Collectors.toUnmodifiableMap(
fruit -> fruit, // Key mapper: the fruit itself
fruit -> fruit.length() // Value mapper: the length of the fruit name
));
System.out.println(immutableMap);
// Attempting to modify the map will throw UnsupportedOperationException
// immutableMap.put("date", 4); // Throws UnsupportedOperationException
}
}
Notes:
- Unmodifiable vs Immutable: Collections created with
Collectors.toUnmodifiableList(),Collectors.toUnmodifiableSet(), andCollectors.toUnmodifiableMap()are unmodifiable. While they cannot be changed (add, remove, replace), immutability might imply further guarantees (e.g., deeply immutable objects inside the collection, which this does not enforce). - Introduced in Java 10:
toUnmodifiableList(),toUnmodifiableSet(), andtoUnmodifiableMap()were introduced in Java 10. If you’re using Java 8 or Java 9, you’ll need a custom approach for creating immutable collections (likeCollections.unmodifiableList).
In Java 8:
If you’re stuck on Java 8, you can achieve something similar using Collections.unmodifiableList() or other Collections.unmodifiableXxx methods:
package org.kodejava.util.stream;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ImmutableCollectionExample {
public static void main(String[] args) {
List<String> immutableList = Collections.unmodifiableList(
Stream.of("apple", "banana", "cherry").collect(Collectors.toList())
);
System.out.println(immutableList);
// immutableList.add("date"); // Throws UnsupportedOperationException
}
}
This approach, however, wraps an existing modifiable collection, so try to update your project to take advantage of Java 10+ features.
