
Java8 flatMap Example/Tutorial
Java8 introduces a new collection API called the Stream API.The Stream Collection API supports processing streams of data stored within it.
This API has many advantages which will be elaborated in a consolidated post.
Supported operations in Stream API are :
Stream<String>
Stream<Integer>
Stream<String[]>
Stream<ArrayList<String>>
Stream<Set<String>>
Flattening a Stream makes it more easy to iterate and operate over it.
For these reasons it might be required to flatten the Stream like this.
Stream<String[]> --> Stream<String>
Stream<ArrayList<String>> --> Stream<String>
Stream<Set<Integer>> --> Stream<String>
{{1,2}, {3,4}, {5,6}} --> flatten --> {1,2,3,4,5,6}
{{"Java","Jcr"},{"Hello","Java"}} --> flatten --> {"Java","Jcr","Hello","Java"}
ATTENTION:One WRONG thing which you might have learnt.
In some websites its said that Stream Operation like (filter, sum, distinct…) will not work without flattening a Stream.
This is absolutely wrong. All operations will work, its just that flattening a Stream will make your job easier.
I will explain these with examples a the end of this article.
1. Convert Stream<String[]> to Stream<String>
package codermag.net.java8;
import java.util.Arrays;
import java.util.stream.Stream;
public class StringArrayToFlatMap {
public static void main(String[] args) {
String[][] data = new String[][]
{
{ "Java", "Jcr" },
{ "Hello", "Java" },
{ "Coder", "Magnet" }
};
//Converting to Stream<String[]>
Stream<String[]> dataStream = Arrays.stream(data);
//Flattening the Stream to Stream<String>
Stream<String> stringStream = dataStream.flatMap(x -> Arrays.stream(x));
stringStream.forEach(System.out::println);
}
}
2. Convert a Stream<List<String>> to Stream<String>
package codermag.net.java8;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class ListToFlatMap {
public static void main(String[] args) {
List<String> list1=new ArrayList<String>();
list1.add("Hello");
list1.add("Developers");
List<String> list2=new ArrayList<String>();
list2.add("Welcome");
list2.add("To Codermagnet");
List<String> list3=new ArrayList<String>();
list3.add("Wats");
list3.add("Up?");
List<List<String>> itemList=new ArrayList<List<String>>();
itemList.add(list1);
itemList.add(list2);
itemList.add(list3);
//Converting the List of List<String> to Stream
//List<List<String>> --> Stream<List<String>>
Stream<List<String>> listStream=itemList.stream();
//Flattening the Stream<List<String>> to Stream<String>
Stream<String> flattenedStream=listStream.flatMap(x -> x.stream());
flattenedStream.forEach(System.out :: println);
}
}
You don't need a flattened Stream to use methods like filter(),sum()....etc
So just to show that you can apply Stream methods here are some examples.Example 1:
The following example filters arrays whose size is greater than 2.
This shows how you can use filter() on a Stream<String[]> instead of using a flattened Stream<String>.
package codermag.net.java8;
import java.util.Arrays;
import java.util.stream.Stream;
public class FilterWorksOnNonFlattenedStream {
public static void main(String[] args) {
String[][] alphabets = new String[][]
{
{ "a", "b" },
{ "c", "d" },
{ "e", "f", "g" }
};
Stream<String[]> alphabetStream = Arrays.stream(alphabets);
// Filtering out the arrays having more than 2 elements
Stream<String[]> filteredStream = alphabetStream.filter(x -> (x.length > 2));
filteredStream.forEach(x -> System.out.println(Arrays.toString(x)));
}
}
OUTPUT:
[e, f, g]
Example 2:
Filtering out List objects which contain the String "Hello".
This shows how you can use filter() on a Stream<List<String>> instead of using a flattened Stream<String>.
package codermag.net.java8;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class FilterWorksOnNonFlattenedStream2 {
public static void main(String[] args) {
List<String> list1=new ArrayList<String>();
list1.add("Hello");
list1.add("Developers");
List<String> list2=new ArrayList<String>();
list2.add("Welcome");
list2.add("To Codermagnet");
List<String> list3=new ArrayList<String>();
list3.add("Hello");
list3.add("WhatsUp?");
List<List<String>> itemList=new ArrayList<List<String>>();
itemList.add(list1);
itemList.add(list2);
itemList.add(list3);
//Converting the List of List<String> to Stream
//List<List<String>> --> Stream<List<String>>
Stream<List<String>> listStream=itemList.stream();
//Filtering only the List objects containing the string "Hello"
Stream<List<String>> filteredList=listStream.filter(x -> x.contains("Hello"));
filteredList.forEach(System.out :: println);
}
}
OUTPUT:
[Hello, Developers]
[Hello, WhatsUp?]