0

I am getting some issues to convert my data to map, here are my data:

For e.g

[
  [abc, pqr, xyz], 
  [1, 2, 3], 
  [4, 5, 6],
  [1, 7, 8]
]

And i have to convert it into map as follow:

{
  1: [
    {abc:1, pqr:2,xyz:3},
    {abc:1, pqr:7,xyz:8}
  ],
  4: [
    {abc:4, pqr:5,xyz:6}
  ]
}

With basic for I know how to do it but with streaming, I am not getting it as I tried to do it with flatMap, reduce methods with a stream but maybe I am doing something very much wrong. So please can anyone help me out with this?

I tried something to flatMap and all as follow but stuck what to do:

List<List<Object>> dd = new ArrayList<List<Object>>();
final List<Object> dd1 = new ArrayList<Object>();
dd1.add("abc");
dd1.add("pqr");
dd1.add("xyz");
dd.add(dd1);

List<Object> dd2 = new ArrayList<Object>();
dd2.add("1");
dd2.add("2");
dd2.add("3");
dd.add(dd2);

dd2 = new ArrayList<Object>();
dd2.add("4");
dd2.add("5");
dd2.add("6");
dd.add(dd2);

Map<String, Object> m =  dd.stream().collect(Collectors.toMap(s -> (String) s.get(0), s -> s));
System.out.println(m);

Map<String, Object> m1 =  dd.stream().reduce((l1,l2) -> {
    return (new Map<String, Object>()).put(dd1.get(l2), l2);
}).orElse(new Map<String, Object>());

There are syntax errors I know in above code. Also, give some good links where can learn to stream nicely.

1
  • 2
    One thing I would advise is to separate the headers first, and then stream only the part that you want to rearrange. The headers are a special case here and should be used as a second input to the streaming. Once you do that, it becomes a lot simpler. Commented Jul 16, 2019 at 10:43

2 Answers 2

1
// get header and remove it from dataframe
List<String> header = dd.remove(0);

// key -> first element of row
// value -> extract from getValue method
// merge function -> merge both lists in case of conflict
Map<String, List<Map<String, String>>> tableAsMap = dd.stream().collect(Collectors.toMap(row -> row.get(0), row -> getValue(row, header), (list1, list2) -> {
    list1.addAll(list2);
    return list1;
}));

public List<Map<String, String>> getValue(List<String> row, List<String> header) {
    Map<String, String> map = new HashMap<>();
    IntStream.range(0, header.size())
            .forEach(idx -> map.put(header.get(idx), row.get(idx)));
    List<Map<String, String>> ret = new ArrayList<>();
    ret.add(map);
    return ret;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Using dd.get(0) and dd.remove(0) is redundant, as List.remove() returns the removed item (docs).
0

You can simplify your whole code to this:

List<String> header = dd.remove(0);
Map<Integer, List<Map<String, Integer>>> result = dd.stream()
        .map(row -> IntStream.range(0, Math.min(row.size(), header.size())).boxed()
                .collect(Collectors.toMap(header::get, i -> Integer.parseInt(row.get(i)))))
        .collect(Collectors.groupingBy(m -> m.get("abc")));

First use extract the header using List.remove(). After that you create a map for each row by replacing the list index with the header field as key (also parse the value as int). Finally you can use Collectors.groupingBy() with m -> m.get("abc") to group the result by the abc value.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.