按列表<map <string,object =“” >>到Map <integer,list <integer =“” >>的Java流分组

时间:2018-08-22 21:05:50

标签: java java-stream

我有一个

List<Map<String, Object>>

来自Spring NamedParameterJdbcTemplate queryForList调用。数据返回看起来像这样:

[{"id":5,"uid":6}, {"id":5,"uid":7}, {"id":6,"uid":8}, {"id":7,"uid":7}, {"id":8,"uid":7}, {"id":8,"uid":9}]

如何重新排列以下格式的数据?

{5:[6, 7], 6:[8], 7:[7], 8:[7, 9]}

我想返回一个Map<Integer, List<Integer>>

任何人都知道我如何实现这一目标?任何帮助,不胜感激??

3 个答案:

答案 0 :(得分:6)

这是Collectors.groupingBy的工作,它具有像Collectors.mapping这样的下游收集器

 Map<Integer, List<Integer>> result = l.stream()
            .collect(Collectors.groupingBy(
                    m -> (Integer) (m.get("id")),
                    Collectors.mapping(m -> (Integer) m.get("uuid"), Collectors.toList())));

或者根本没有流:

list.forEach(x -> {
        Integer key = (Integer) x.get("id");
        Integer value = (Integer) x.get("uuid");
        result.computeIfAbsent(key, ignoreMe -> new ArrayList<>()).add(value);
    });

答案 1 :(得分:2)

您可以在使用分组收集器时将键和值映射为整数:

List<Map<String, Object>> maps = null;

Map<Integer, List<Integer>> result = maps.stream()
        .collect(Collectors.groupingBy(
                map -> ((Number) map.get("id")).intValue(),
                    Collectors.mapping(map -> ((Number) map.get("uid")).intValue(), 
                            Collectors.toList())));

使用((Number) map.get("id")).intValue()以防万一该值是Long。

答案 2 :(得分:0)

我不是流API语法的忠实拥护者:我认为使用普通的旧循环(以及其他一些Java 8-ism)可能会更容易:

Map<Integer, List<Integer>> result = new HashMap<>();
for (Map<String, Object> entry : list) {
  int id = (Integer) entry.get("id");
  int uid = (Integer) entry.get("uid");
  result.computeIfAbsent(id, k -> new ArrayList<>())
      .add(uid);
}

YMMV,当然;我只是认为,这比所有使用收集器和下游收集器的麻烦以及出现类型错误时发出的非显而易见的错误消息都更为愉快。