9

I have been messing around with Java 8 Stream API and ran into something I could only do through traditional for-loops.

Given a nested map of

{ 1999: { 3: [23, 24, 25], 4: [1, 2, 3] }, 2001: { 11: [12, 13, 14], 12: [25, 26, 27] } } 

How can I transform this into

['23,3,1999', '24,3,1999', '25,3,1999', '1,4,1999', '2,4,1999', '3,4,1999', '12,11,2001', '13,11,2001', '14,11,2001', '25,12,2001', '26,12,2001', '27,12,2001'] 

Basically I want to replicate:

 Map<Integer, Map<Integer, List<Integer>>> dates... List<String> flattened = new ArrayList<>(); for (Integer key1 : map.keySet()) { for (Integer key2 : map.get(key1).keySet()) { for (Integer value : map.get(key1).get(key2)) { flattened.add(value + "," + key2 + "," + key1); } } } 
0

3 Answers 3

15

Try this for example:

public static void main(String[] args) { Map<Integer, Map<Integer, List<Integer>>> dates = new HashMap<Integer, Map<Integer, List<Integer>>>() {{ put(1999, new HashMap<Integer, List<Integer>>() {{ put(3, Arrays.asList(23, 24, 25)); put(4, Arrays.asList(1, 2, 3)); }}); put(2001, new HashMap<Integer, List<Integer>>() {{ put(11, Arrays.asList(12, 13, 14)); put(12, Arrays.asList(25, 26, 27)); }}); }}; dates.entrySet().stream().flatMap(year -> year.getValue().entrySet().stream().flatMap(month -> month.getValue().stream() .map(day -> day + "," + month.getKey() + "," + year.getKey()))) .forEach(System.out::println); } 

and if you need them sorted by year then month then day try this:

 dates.entrySet().stream().flatMap(year -> year.getValue().entrySet().stream().flatMap(month -> month.getValue().stream() .map(day -> Arrays.asList(year.getKey(), month.getKey(), day)))) .sorted(Comparator.comparing(l -> l.get(0)*10000 + l.get(1)*100 + l.get(2))) .forEach(System.out::println); 
Sign up to request clarification or add additional context in comments.

Comments

6
 items .entrySet() .stream() .flatMap( l-> l.getValue().entrySet().stream() .flatMap( ll->ll.getValue().stream() .map(lll+","+ll.getKey()+","+l.getKey()))) .collect(Collectors.toList()) .forEach(System.out::println); 

Comments

3

Assuming there is a Holder that can take 3 integers for example:

 static class Holder { private final int first; private final int second; private final int third; } 

And these are some nested maps, then 2 flatMap will achieve what you want:

 List<Holder> holders = map.entrySet().stream().flatMap( e -> e.getValue() .entrySet() .stream() .flatMap(x -> x.getValue().stream().map(y -> new Holder(e.getKey(), x.getKey(), y)))) .collect(Collectors.toList()); System.out.println(holders); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.