Monday, 16 January 2017

FlatMap in Java

If you know about the mapping operation in Java stream, in mapping operation the given function is applied to all the elements of the stream.

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

  1. Collecting in Java Stream API
  2. Reduction Operations in Java Stream API
  3. Parallel Stream in Java Stream API
  4. Java Stream API Examples
  5. Primitive type streams in Java Stream API
  6. Method reference in Java 8

You may also like -

>>>Go to Java advance topics page

No comments:

Post a Comment