Java 8 List of Objects to Map<String, List> of values

Rinsen S :

I am trying to convert List<Object> to Map<String, List> using Streams,

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

I have List<Users>, and need to collect into Map<String, Object> m,

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

to be use in named query -> eg: select * from table ... where names in (:names) and age in (:age) and org in (:org)

as of now I am doing like

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());

How to collect all the values while streaming to the list only once ?

Eran :

I believe something like this should work:

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())));

It converts each User to a Map<String,String> (containing the 3 required properties indexed by the required keys), and then groups the entries of all the user maps by their keys.

EDIT:

Here's another alternative that creates the Map.Entrys directly instead of creating the small HashMaps, so it should be more efficient:

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())));

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=472066&siteId=1