Reputation: 660
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.
Upvotes: 0
Views: 430
Reputation: 655
// 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;
}
Upvotes: 1
Reputation: 11032
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.
Upvotes: 0