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

Rin*_*n S 5 java java-8

我想转换List<Object>Map<String, List>使用Streams,

public class User{
   String name;
   String age;
   String org;
}
Run Code Online (Sandbox Code Playgroud)

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

 m.put("names", List of names,);
 m.put("age", List of age);
 m.put("org", List of org);
Run Code Online (Sandbox Code Playgroud)

在命名查询中使用 - >例如: 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());
Run Code Online (Sandbox Code Playgroud)

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

Era*_*ran 9

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

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())));
Run Code Online (Sandbox Code Playgroud)

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

编辑:

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

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())));
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael 6

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));
Run Code Online (Sandbox Code Playgroud)

  • 是的它也很干净而且非常感谢它! (2认同)
  • 即使有数百万用户,如果这种解决方案,流式传输三次比替代方案更有效,我也不会感到惊讶.流式传输列表本身并不是一项昂贵的操作.与此答案的三个散列操作相比,至少不如执行三百万个散列操作那么昂贵. (2认同)