Friday, 6 May 2016

Java8 flatMap Example

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?]




No comments:

Post a Comment

Coder Magnet
CoderMagnet is full of resources from our daily development activities. It has solutions for common problematic scenarios in technologies like Java 8, AEM, JCR and also occasionally gives you tips on Blogger as well.