Showing posts with label flatMap. Show all posts
Showing posts with label flatMap. Show all posts

Friday, 26 March 2021

How to flatten nested maps recursively?

Using ‘flatmap’ function of a stream, you can flatten the nested maps recursively.

 

Find the below working application.

 

FlatMapUtil.java

package com.sample.app;

import java.util.AbstractMap.SimpleEntry;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class FlatMapUtil {
	public static Map<String, Object> flatten(Map<String, Object> mapToFlatten) {
		return mapToFlatten.entrySet().stream().flatMap(FlatMapUtil::flatten).collect(LinkedHashMap::new,
				(map, entry) -> map.put(entry.getKey(), entry.getValue()), LinkedHashMap::putAll);
	}

	private static Stream<Entry<String, Object>> flatten(Map.Entry<String, Object> entry) {

		if (entry == null) {
			return Stream.empty();
		}

		Object value = entry.getValue();

		if (value instanceof Map<?, ?>) {
			Map<?, ?> properties = (Map<?, ?>) value;
			return properties.entrySet().stream()
					.flatMap(e -> flatten(new SimpleEntry<>(entry.getKey() + "." + e.getKey(), e.getValue())));
		}

		if (value instanceof List<?>) {
			List<?> list = (List<?>) value;
			return IntStream.range(0, list.size())
					.mapToObj(i -> new SimpleEntry<String, Object>(entry.getKey() + "[" + i + "]", list.get(i)))
					.flatMap(FlatMapUtil::flatten);
		}

		return Stream.of(entry);
	}
}

 

FlatMapDemo.java

package com.sample.app;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FlatMapDemo {
	public static void main(String args[]) {
		Map<String, Object> employeeDetails = new HashMap<>();

		Map<String, Object> emp1Details = new HashMap<>();

		Map<String, String> name = new HashMap<>();
		name.put("firstName", "Krishna");
		name.put("lastName", "Gurram");
		emp1Details.put("name", name);

		Map<String, Object> address1 = new HashMap<>();
		address1.put("city", "Bangalore");
		address1.put("state", "Karnataka");
		address1.put("country", "India");

		List<Map<String, Object>> emp1Addresses = new ArrayList<>();
		emp1Addresses.add(address1);

		emp1Details.put("addresses", emp1Addresses);

		employeeDetails.put("emp1", emp1Details);

		Map<String, Object> map = FlatMapUtil.flatten(employeeDetails);

		for (String key : map.keySet()) {
			System.out.println(key + " -> " + map.get(key));
		}

	}
}

 

Output

emp1.addresses[0].country -> India
emp1.addresses[0].city -> Bangalore
emp1.addresses[0].state -> Karnataka
emp1.name.firstName -> Krishna
emp1.name.lastName -> Gurram

 

 

 

 

  

Previous                                                    Next                                                    Home

Wednesday, 18 March 2020

Java: map vs flatMap

a. map function takes a stream as input and transform it to other stream. For example, I can use map function to convert a stream of integers to stream of squares.
‘flatMap’ method returns a stream consisting of the results by replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream.

Signature
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

For example, let’s use flatMap to convert Stream<List<Integer>> to Stream<Integer>.
App.java

package com.sample.app;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class App {

 public static void main(String args[]) {

  // map demo
  List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

  List<Integer> squares = numbers.stream().map(number -> number * number).collect(Collectors.toList());

  squares.stream().forEach(n -> System.out.print(n + " "));

  // flatMap demo
  List<Integer> primeNumbers = Arrays.asList(2, 3, 5, 7);
  List<Integer> evenNumbers = Arrays.asList(2, 4, 6, 8);
  List<Integer> oddNumbers = Arrays.asList(1, 3, 5, 7);

  List<List<Integer>> allTypeOfNumbers = Arrays.asList(primeNumbers, evenNumbers, oddNumbers);

  List<Integer> allNumbers = allTypeOfNumbers.stream().flatMap(list -> list.stream())
    .collect(Collectors.toList());

  System.out.println();
  allNumbers.stream().forEach(ele -> System.out.print(ele + " "));

 }

}


Output
1 4 9 16 25
2 3 5 7 2 4 6 8 1 3 5 7


b. map() is used to transform the data, whereas flatMap can be used for both transformation and flatening.


You may like

flatMap: Convert Stream to Stream

‘flatMap’ method returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream.

Signature
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

Example
Integer[] primeNumbers = { 2, 3, 5, 7 };
Integer[] evenNumbers = { 2, 4, 6, 8 };
Integer[] oddNumbers = { 1, 3, 5, 7 };

Integer[][] allTypeOfNumbers = { primeNumbers, evenNumbers, oddNumbers };

Stream<Integer[]> allNumbers = Arrays.stream(allTypeOfNumbers);

Stream<Integer> intStream = allNumbers.flatMap(arr -> Arrays.stream(arr));

App.java
package com.sample.app;

import java.util.Arrays;
import java.util.stream.Stream;

public class App {

 public static void main(String args[]) {
  Integer[] primeNumbers = { 2, 3, 5, 7 };
  Integer[] evenNumbers = { 2, 4, 6, 8 };
  Integer[] oddNumbers = { 1, 3, 5, 7 };

  Integer[][] allTypeOfNumbers = { primeNumbers, evenNumbers, oddNumbers };

  Stream<Integer[]> allNumbers = Arrays.stream(allTypeOfNumbers);

  Stream<Integer> intStream = allNumbers.flatMap(arr -> Arrays.stream(arr));

  intStream.forEach(ele -> System.out.print(ele + ", "));
 }

}

Output
2, 3, 5, 7, 2, 4, 6, 8, 1, 3, 5, 7,


Previous                                                    Next                                                    Home

Java8: flatMap example

‘flatMap’ method returns a stream consisting of the results by replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream.

Signature
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

For example, let’s use flatMap to convert Stream<List<Integer>> to Stream<Integer>.

Example
List<Integer> primeNumbers = Arrays.asList(2, 3, 5, 7);
List<Integer> evenNumbers = Arrays.asList(2, 4, 6, 8);
List<Integer> oddNumbers = Arrays.asList(1, 3, 5, 7);

List<List<Integer>> allTypeOfNumbers = Arrays.asList(primeNumbers, evenNumbers, oddNumbers);

List<Integer> allNumbers = allTypeOfNumbers.stream().flatMap(list -> list.stream()).collect(Collectors.toList());

App.java
package com.sample.app;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class App {

 public static void main(String args[]) {
  List<Integer> primeNumbers = Arrays.asList(2, 3, 5, 7);
  List<Integer> evenNumbers = Arrays.asList(2, 4, 6, 8);
  List<Integer> oddNumbers = Arrays.asList(1, 3, 5, 7);

  List<List<Integer>> allTypeOfNumbers = Arrays.asList(primeNumbers, evenNumbers, oddNumbers);

  List<Integer> allNumbers = allTypeOfNumbers.stream().flatMap(list -> list.stream())
    .collect(Collectors.toList());

  allNumbers.stream().forEach(ele -> System.out.print(ele + ", "));
 }

}

Output
2, 3, 5, 7, 2, 4, 6, 8, 1, 3, 5, 7,




Previous                                                    Next                                                    Home