Shakthi
Shakthi

Reputation: 864

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);
    }
}

Upvotes: 9

Views: 9339

Answers (2)

Samuel Philipp
Samuel Philipp

Reputation: 11050

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}}

Upvotes: 6

Kartik
Kartik

Reputation: 7917

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.

Upvotes: 4

Related Questions