Java 8 对象列表以映射 <String, List> 的值

新手上路,请多包涵

我正在尝试使用 --- 将 List<Object> 转换为 Map<String, List> Streams

 public class User{
   String name;
   String age;
   String org;
}

我有 List<Users> ,需要收集到 Map<String, Object> m

  m.put("names", List of names,);
 m.put("age", List of age);
 m.put("org", List of org);

在命名查询中使用 -> 例如: select * from table ... where names in (:names) and age in (:age) and org in (:org)

截至目前,我正在做

List<String> names = userList.stream().map(User::getName).collect(Collectors.toList());
List<String> age= userList.stream().map(User::getAge).collect(Collectors.toList());
List<String> org= userList.stream().map(User::getName).collect(Collectors.toList());

如何在仅流式传输到列表一次的同时收集所有值?

原文由 Rinsen S 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 407
2 个回答

我相信这样的事情应该有效:

 Map<String,List<String>> map =
    userList.stream()
            .flatMap(user -> {
                Map<String,String> um = new HashMap<>();
                um.put("names",user.getName());
                um.put("age",user.getAge());
                um.put("org",user.getOrg());
                return um.entrySet().stream();
            }) // produces a Stream<Map.Entry<String,String>>
            .collect(Collectors.groupingBy(Map.Entry::getKey,
                                           Collectors.mapping(Map.Entry::getValue,
                                                              Collectors.toList())));

它将每个 User 转换为 Map<String,String> (包含由所需键索引的 3 个必需属性),然后按键对所有用户映射的条目进行分组。

编辑:

这是另一种替代方法,它直接创建 Map.Entry 而不是创建小的 HashMap s,因此它应该更有效:

 Map<String,List<String>> map =
    userList.stream()
            .flatMap (user -> Stream.of (new SimpleEntry<>("names",user.getName()),
                                         new SimpleEntry<>("age",user.getAge()),
                                         new SimpleEntry<>("org",user.getOrg())))
            .collect(Collectors.groupingBy(Map.Entry::getKey,
                                           Collectors.mapping(Map.Entry::getValue,
                                                              Collectors.toList())));

原文由 Eran 发布,翻译遵循 CC BY-SA 4.0 许可协议

Eran 向您 展示了如何使用流来实现这一点。正如您希望看到的那样,它非常丑陋。

如果您的程序版本的问题是代码重复的数量,那么除了流之外,我们还可以使用其他方法来解决该问题。

我会将集合重构为它自己的方法:

 private static List<String> getProperty(List<User> users, Function<User, String> getter) {
    return users.stream().map(getter).collect(Collectors.toList());
}

Map<String,List<String>> map = new HashMap<>();
map.put("names", getProperty(userList, User::getName));
map.put("age",   getProperty(userList, User::getAge));
map.put("org",   getProperty(userList, User::getOrg));

原文由 Michael 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题