Java 8: How to convert List to Map>?

前端 未结 5 1591
隐瞒了意图╮
隐瞒了意图╮ 2021-01-01 17:25

I have a List of String like:

List locations = Arrays.asList(\"US:5423\",\"US:6321\",\"CA:1326\",\"AU:5631\");

And I want to

相关标签:
5条回答
  • 2021-01-01 17:52

    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())));
    
    0 讨论(0)
  • 2021-01-01 18:02

    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;
    }
    
    0 讨论(0)
  • 2021-01-01 18:04

    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())));
    
    0 讨论(0)
  • 2021-01-01 18:09

    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() ) ) );
    
    0 讨论(0)
  • 2021-01-01 18:10

    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]}
    
    0 讨论(0)
提交回复
热议问题