Where as flattening a structure, in simple terms, means bringing all the nested structures at the same level. If you have a data structure with many nested levels flattening will break all the nested levels and bring all the elements at the same level.
As example if you have a list of Strings, list<String> like - [[“a”, “b”, “c”], [“c”, “d”], [“c”, “e”, “f”]] then flattening it will bring everything to the same level and the structure you will have be like this -
[“a”, “b”, “c”, “c”, “d”, “c”, “e”, “f”].
Bringing them both together in a method flatMap() means, function will be applied to all the elements of the stream and then it will be flatten to have a single level structure.
FlatMap example
Let’s say there is a class called Order which has a collection of items. If you have a stream of orders you can get a stream containing all the items in all the orders like this -
Order class
public class Order {
private String orderId;
private List<String> items;
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public List<String> getItems() {
return items;
}
public void setItems(List<String> items) {
this.items = items;
}
}
Getting a stream containing all the items in all the orders
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class FlatMapDemo {
public static void main(String[] args) {
List<Order> orderList = getOrderList();
Stream<String> item = orderList.stream().flatMap(order -> order.getItems().stream());
item.forEach(System.out::println);
}
/**
*
* @return
*/
private static List<Order> getOrderList(){
List<Order> orderList = new ArrayList<Order>();
Order order = new Order();
order.setOrderId("1");
order.setItems(Arrays.asList("Item1", "Item2", "Item3"));
orderList.add(order);
order = new Order();
order.setOrderId("2");
order.setItems(Arrays.asList("Item3", "Item5"));
orderList.add(order);
return orderList;
}
}
Output
Item1
Item2
Item3
Item3
Item5
Here you can see using flatMap() you are getting all the items which are stored as a list inside orders.
Methods for primitive data types
In Java stream API there are variants of flatMap method which work with primitive data types. These methods are -
- flatMapToInt() - Works with int data type. Returns a new IntStream.
- flatMapToLong() - Works with long data type. Returns a new LongStream.
- flatMapToDouble() - Works with double data type. Returns a new DoubleStream.
flatMapToInt example
If you have 2D array and you want to flatten it and get a new IntStream you can get it like this -
int[][] numArray = {{1, 2}, {3, 4}, {5, 6}};
Stream<int[]> numStream = Stream.of(numArray);
IntStream iStream = Stream.of(numArray).flatMapToInt(n -> Arrays.stream(n));
iStream.forEach(System.out::println);
Output
1
2
3
4
5
6
In the lambda expression n -> Arrays.stream(n), n denotes one of the array with in the 2D array, so first time {1,2} will be passed as the mapped stream and its contents will be placed in the new IntStream, next time another array {3,4} will be passed and so on.
That's all for this topic FlatMap in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!
Related Topics
You may also like -