I have a List of String like:
List locations = Arrays.asList(\"US:5423\",\"US:6321\",\"CA:1326\",\"AU:5631\");
And I want to
You may do it like so:
Map<String, List<String>> locationMap = locations.stream()
.map(s -> s.split(":"))
.collect(Collectors.groupingBy(a -> a[0],
Collectors.mapping(a -> a[1], Collectors.toList())));
A much more better approach would be,
private static final Pattern DELIMITER = Pattern.compile(":");
Map<String, List<String>> locationMap = locations.stream()
.map(s -> DELIMITER.splitAsStream(s).toArray(String[]::new))
.collect(Collectors.groupingBy(a -> a[0],
Collectors.mapping(a -> a[1], Collectors.toList())));
Update
As per the following comment, this can be further simplified to,
Map<String, List<String>> locationMap = locations.stream().map(DELIMITER::split)
.collect(Collectors.groupingBy(a -> a[0],
Collectors.mapping(a -> a[1], Collectors.toList())));
What about POJO. It looks not complicated comparing with streams.
public static Map<String, Set<String>> groupByCountry(List<String> locations) {
Map<String, Set<String>> map = new HashMap<>();
locations.forEach(location -> {
String[] parts = location.split(":");
map.compute(parts[0], (country, codes) -> {
codes = codes == null ? new HashSet<>() : codes;
codes.add(parts[1]);
return codes;
});
});
return map;
}
Try this
Map<String, List<String>> locationMap = locations.stream()
.map(s -> new AbstractMap.SimpleEntry<String,String>(s.split(":")[0], s.split(":")[1]))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
You can just put the code in grouping by part where you put first group as key and second as value instead of mapping it first
Map<String, List<String>> locationMap = locations
.stream()
.map(s -> s.split(":"))
.collect( Collectors.groupingBy( s -> s[0], Collectors.mapping( s-> s[1], Collectors.toList() ) ) );
Seems like your location map needs to be sorted based on keys, you can try the following
List<String> locations = Arrays.asList("US:5423", "US:6321", "CA:1326", "AU:5631");
Map<String, List<String>> locationMap = locations.stream().map(str -> str.split(":"))
.collect(() -> new TreeMap<String, List<String>>(), (map, parts) -> {
if (map.get(parts[0]) == null) {
List<String> list = new ArrayList<>();
list.add(parts[1]);
map.put(parts[0], list);
} else {
map.get(parts[0]).add(parts[1]);
}
}, (map1, map2) -> {
map1.putAll(map2);
});
System.out.println(locationMap); // this outputs {AU=[5631], CA=[1326], US=[5423, 6321]}