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

No comments:

Post a Comment