Java 8 Stream convert List

1. Introduction

In this quick tutorial, we'll explain how to convert a List of elements to a String. This can be useful in certain scenarios, like printing the contents to the console in a human-readable form for inspection/debugging.

Other (Discouraged) Tactics of Converting Streams to Lists

The Stream API discourages the introduction of side effects into the stream pipeline. Because streams may be exposed to parallel threads, it is dangerous to attempt to modify an externally declared source container.

Thus, the two following examples of using Stream.forEach() and Stream.reduce() when you want to convert a stream to list are bad hacks.

Piggybacking on Stream.forEach()

Without parallelism, this works just fine and the code will produce the results you want but it's not future-proof and is best avoided.

Convert a Stream to List using Stream.reduce()

Conclusion

The Stream API introduced multiple ways of making Java more functional in nature. Because streams help operations to run in parallel, it is important that optional intermediate and terminal operations uphold the principles of:

  • Non-interference
  • Minimizing side effects
  • Keeping operation behaviors stateless

Among the tactics that this article has explored, the use of collectors is the one that promises to help you achieve all the three principles. It is thus important that as you continue working with streams, you improve your skills of handling both pre-defined and custom collectors.

The source code for this guide is available on GitHub.

1. Different Ways to Collect Stream Items into List

There are primarily three ways to collect stream items into a list. Let’s compare them.

1.1. Stream.toList()

  • The toList() method has been added in Java 16. It is a default method that collects the stream items into an unmodifiable List.
  • The returned list is an implementation of Collections.unmodifiableList(new ArrayList<>(Arrays.asList(stream.toArray()))) where stream represents the underlying Stream of items.
  • The order of the items in the list will be same as the order in stream, if there is any.
  • As the returned List is unmodifiable; calls to any mutator method will always cause UnsupportedOperationException to be thrown.
  • It is a terminal operation.
Stream<String> tokenStream = Stream.of("A", "B", "C", "D"); List<String> tokenList = tokenStream.toList();

1.2. Stream.collect(Collectors.toUnmodifiableList())

  • This method has been added in Java 10. It is a terminal operation that collects the stream items into an unmodifiable List.
  • The returned list is an instance of Collections.unmodifiableList() that is filled with stream items using JDK internal APIs able to access private methods of the JDK classes without using the reflection. In this case, the unmodifiable list is an implementation of SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(list.toArray()) where the list is an intermediate and mutable list of stream items.
  • The List does not allow the null values and the whole operation will throw the NullPointerException if there is a null value in the stream.
  • The order of items in the list is the same as the order of items in the stream, if there is any.
Stream<String> tokenStream = Stream.of("A", "B", "C", "D"); List<String> tokenList = tokenStream.collect(Collectors.toUnmodifiableList());

1.3. Stream.collect(Collectors.toList())

  • This method has been added in Java 8, along with the original Stream API. It is a terminal operation that collects the stream items into a mutable List.
  • The returned list is an instance of ArrayList class.
  • Similar to other versions, the order of the items in the mutable list will be same as the order in stream, if there is any.
Stream<String> tokenStream = Stream.of("A", "B", "C", "D"); List<String> tokenList = tokenStream.collect(Collectors.toList());

Java 8 – Converting a List to String with Examples

Posted by: Venkatesh Nukala in Core Java July 5th, 2021 0

A quick guide to convert List to String in java using different methods and apache commons api with examples.

1. Introduction


In this article, We'll learn about java 8 new Stream API flatMap() method. When to use it and how to use it.

flatMap() method is used to convert or flatten Stream of collections into Stream of collection values by removing the collection.

Removing collection such as List or Set from Stream is called flattening.

FlatMap() is part of Stream Intermediate Operations in Java 8.

Java 8, Stream can hold any type of collections and can be converted into Stream<T> as below.

Stream<List<List<String>>> --> apply flatMap() logic --> Stream<String> Stream<Set<Set<String>>> --> apply flatMap() logic --> Stream<String> Stream<List<String>>> --> apply flatMap() logic --> Stream<String> Stream<List<Object>>> --> apply flatMap() logic --> Stream<Object>

1. Using Java 8

We can use Java 8 Stream to convert List<Integer> to List<String>. Following are the complete steps:

  1. Convert List<Integer> to Stream<Integer> using List.stream().
  2. Convert Stream<Integer> to Stream<String> using Stream.map().
  3. Accumulate Stream<String> into List<String> using Collectors.toList().

The following program demonstrates it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
class Main
{
public static void main(String[] args)
{
List<Integer> list = Arrays.asList( 1, 2, 3, 4, 5 );
List<String> newList = list.stream()
.map(String::valueOf)
.collect(Collectors.toList());
System.out.println(newList);// [1, 2, 3, 4, 5]
}
}

DownloadRun Code


It is recommended to use method references for referring to an existing method instead of a lambda expression. For converting an integer to a string, we can pass String::valueOf to the map() method.

Using Generics:

Following is the generic version of the above program. It passes the method reference as a parameter to the generic function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
class Main
{
// Generic method to convert `List<Integer>` to `List<String>`
public static <T, U> List<U> transform(List<T> list, Function<T, U> function)
{
return list.stream()
.map(function)
.collect(Collectors.toList());
}
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<String> newList = transform(list, String::valueOf);
System.out.println(newList);// [1, 2, 3, 4, 5]
}
}

DownloadRun Code


Here’s an equivalent version without using the Stream API.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
class Main
{
// Generic method to convert `List<Integer>` to `List<String>`
public static <T, U> List<U> transform(List<T> list, Function<T, U> function)
{
List<U> result = new ArrayList<>();
for (T t : list) {
U u = function.apply(t);
result.add(u);
}
return result;
}
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<String> newList = transform(list, String::valueOf);
System.out.println(newList);// [1, 2, 3, 4, 5]
}
}

DownloadRun Code