Reputation: 804
What I have: (2 lists)
List<String> keys = Arrays.asList("1", "2", "3");
List<String[]> values = Arrays.asList("a,aa,aaa".split(","), "b,bb,bbb".split(","));
What I'm trying to get: (list of map)
[
{"1": "a", "2": "aa", "3": "aaa"},
{"1": "b", "2": "bb", "3": "bbb"}
]
Java 7 Solution:
List<Map<String,String>> list = new LinkedList<Map<String,String>>();
for(String[] vs: values) {
Map<String, String> map = new LinkedHashMap<String, String>();
for(int i = 0; i < keys.size(); i++) {
map.put(keys.get(i), vs[i]);
}
list.add(map);
}
I'm learning Java 8 and steam. I wonder if it's possible to do it cleaner.
Upvotes: 3
Views: 1483
Reputation: 91
Please find below two ways to achieve this using java 8 stream:
List values =Arrays.asList("a,aa,aaa".split(","), "b,bb,bbb".split(","));
List<Map<String, String>> maps= values.stream().map(l-> IntStream.range(0, l.length).boxed().collect(Collectors.toMap(i-> String.valueOf(i+1), j-> l[j]))).collect(Collectors.toList());
System.out.println("Printing list of map using boxed"+ maps);
List<Map<String, String>> maps2= values.stream().map(l-> IntStream.range(0, l.length).mapToObj(a-> Integer.valueOf(a)).collect(Collectors.toMap(i-> String.valueOf(i+1), j-> l[j]))).collect(Collectors.toList());
System.out.println("Printing list of map using maptoObject"+ maps2);
Upvotes: 0
Reputation: 50716
One approach is to iterate over values
and then iterate over the indexes of each array, matching them to the corresponding index in keys
:
List<Map<String, String>> maps = values.stream()
.map(a -> IntStream.range(0, keys.size())
.boxed()
.collect(Collectors.toMap(keys::get, i -> a[i])))
.collect(Collectors.toList());
The intermediate boxing is unfortunately necessary in order to use the toMap()
collector. If you want to avoid the overhead of boxed indexing, you can define a custom collector in the inner stream:
IntStream.range(0, keys.size())
.collect(HashMap<String, String>::new,
(m, i) -> m.put(keys.get(i), a[i]),
HashMap::putAll)
Upvotes: 2