Converting a Stream to a List is one of the most common stream operations. There are several ways to do it depending on your Java version and whether you need a mutable list.
Method 1: collect(Collectors.toList()) — Java 8+
The classic approach using the collect() terminal operation:
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
List<Integer> list = stream.collect(Collectors.toList());
System.out.println(list); // [1, 2, 3, 4, 5]
This returns a mutable ArrayList. You can add or remove elements from the result.
Method 2: Stream.toList() — Java 16+
Java 16 introduced a shorter, built-in method:
List<Integer> list = Stream.of(1, 2, 3, 4, 5).toList();
System.out.println(list); // [1, 2, 3, 4, 5]
Important:Stream.toList()returns an unmodifiable list. Trying to add or remove elements will throwUnsupportedOperationException. Use this when you don't need to mutate the result.
Method 3: collect(Collectors.toUnmodifiableList()) — Java 10+
If you want an unmodifiable list but are on Java 10–15:
List<Integer> list = Stream.of(1, 2, 3, 4, 5)
.collect(Collectors.toUnmodifiableList());
Method 4: Collecting to a Specific List Type
If you need a specific List implementation (e.g., LinkedList):
import java.util.LinkedList;
import java.util.stream.Collectors;
List<Integer> linkedList = Stream.of(1, 2, 3, 4, 5)
.collect(Collectors.toCollection(LinkedList::new));
Common Pattern: Filter, Transform, Collect
The real power shows when you chain operations before collecting:
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
List<String> names = Stream.of("alice", "bob", "charlie", "dave", "eve")
.filter(name -> name.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(names); // [ALICE, CHARLIE, DAVE]
Which Method to Use?
| Method | Java Version | Mutable? | Notes |
|---|---|---|---|
collect(Collectors.toList()) | 8+ | Yes | Most common, returns ArrayList |
Stream.toList() | 16+ | No | Shortest syntax |
collect(Collectors.toUnmodifiableList()) | 10+ | No | Explicit about immutability |
collect(Collectors.toCollection(...)) | 8+ | Yes | When you need a specific type |
For most cases on Java 16+, prefer Stream.toList() for its conciseness. On Java 8–15, use collect(Collectors.toList()).
Converting IntStream / LongStream to List
Primitive streams (IntStream, LongStream, DoubleStream) can't collect directly to List<Integer>. Use boxed() first to convert each primitive to its wrapper type:
// IntStream to List<Integer>
List<Integer> intList = IntStream.range(1, 6)
.boxed()
.collect(Collectors.toList());
System.out.println(intList); // [1, 2, 3, 4, 5]
// LongStream to List<Long>
List<Long> longList = LongStream.of(100L, 200L, 300L)
.boxed()
.collect(Collectors.toList());
// int[] array to List<Integer>
int[] arr = {10, 20, 30};
List<Integer> fromArray = Arrays.stream(arr)
.boxed()
.collect(Collectors.toList());
The boxed() call is required because List is a generic type and can't hold primitive int — only reference type Integer.
Collecting to Set and Map
The same pattern works for other collection types:
// Collect to a Set (deduplication)
Set<String> uniqueNames = Stream.of("alice", "bob", "alice", "charlie")
.collect(Collectors.toSet());
// Collect to a Map (key = string, value = its length)
Map<String, Integer> nameLengths = Stream.of("alice", "bob", "charlie")
.collect(Collectors.toMap(
name -> name, // key function
String::length // value function
));
Handling Null Elements
Both Collectors.toList() and Stream.toList() accept null elements in the stream. However, Stream.toList()'s unmodifiable list permits null values, while Collectors.toUnmodifiableList() throws a NullPointerException if the stream contains nulls:
Stream<String> withNull = Stream.of("a", null, "b");
// Works fine — ArrayList allows null
List<String> mutable = withNull.collect(Collectors.toList());
// Works fine — Stream.toList() allows null
Stream<String> withNull2 = Stream.of("a", null, "b");
List<String> immutable = withNull2.toList();
// Throws NullPointerException!
Stream<String> withNull3 = Stream.of("a", null, "b");
List<String> noNull = withNull3.collect(Collectors.toUnmodifiableList());
If your stream may contain nulls and you want an unmodifiable list, use Stream.toList() rather than Collectors.toUnmodifiableList().
Summary
collect(Collectors.toList()) is the standard way to convert a Stream to a List. On Java 16+, Stream.toList() is cleaner and should be your default when you don't need to mutate the result. For primitive streams (IntStream, etc.), call boxed() before collecting. Watch out for null handling differences between the unmodifiable collectors.
No comments :
Post a Comment
Please leave your message queries or suggetions.
Note: Only a member of this blog may post a comment.