Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Split String and Create Map inside Map

I have a String like 101-1-5,101-2-4,102-1-5,102-2-5,102-3-5,103-1-4.

I want to add this in to a Map<String, Map<String, String>>.

Like: {101={1=5, 2=4}, 102={1=5, 2=5, 3=5}, 103={1=4}}

How to do this using Java 8 stream?

I tried using normal Java. And it works fine.

public class Util {
    public static void main(String[] args) {

        String samp = "101-1-5,101-2-4,102-1-5,102-2-5,102-3-5,103-1-4";

        Map<String, Map<String, String>> m1 = new HashMap<>();
        Map<String, String> m2 = null;

        String[] items = samp.split(",");

        for(int i=0; i<items.length; i++) {
            String[] subitem = items[i].split("-");
            if(!m1.containsKey(subitem[0]) || m2==null) {
                m2 = new HashMap<>();
            }
            m2.put(subitem[1], subitem[2]);
            m1.put(subitem[0], m2);
        }
        System.out.println(m1);
    }
}
like image 659
Shakthi Avatar asked Feb 04 '23 19:02

Shakthi


2 Answers

You can use the following snippet for this:

Map<String, Map<String, String>> result = Arrays.stream(samp.split(","))
        .map(i -> i.split("-"))
        .collect(Collectors.groupingBy(a -> a[0], Collectors.toMap(a -> a[1], a -> a[2])));

First it creates a Stream of your items, which are mapped to a stream of arrays, containing the subitems. At the end you collect all by using group by on the first subitem and create an inner map with the second value as key and the last one as value.

The result is:

{101={1=5, 2=4}, 102={1=5, 2=5, 3=5}, 103={1=4}}
like image 185
Samuel Philipp Avatar answered Feb 06 '23 08:02

Samuel Philipp


Map<String, Map<String, String>> map = Arrays.stream(samp.split(","))
        .map(s -> s.split("-"))
        .collect(Collectors.toMap(
                o -> o[0],
                o -> Map.of(o[1], o[2]),
                (m1, m2) -> Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))));

Map.of is from Java 9, you can use AbstractMap.SimpleEntry if you are on Java 8.

Samuel's answer is better though, much concise.

like image 30
Kartik Avatar answered Feb 06 '23 08:02

Kartik