I have list of Users(id,ssn,name)
and need to convert as Map of list of ssns and list of ids. Could you help with this?
List.of(new User(1, "ssn1", "user1"), new User(2, "ssn2", "user2"), new User(3, "ssn3", "user3"))
Map with 2 keys("SSNs","IDs") and list as value
"SSNs" - List("ssn1","ssn2","ssn3")
"IDs" - List(1,2,3)
public class Test {
public static void main(String[] args) {
List<User> users = List.of(new User(1, "ssn1", "user1"), new User(2, "ssn2", "user2"),
new User(3, "ssn3", "user3"));
Map<String, List<Object>> userMap = users.stream().collect(Collectors.groupingBy(User::getSsn));
}
}
class User {
public int getId() {
return id;
}
public String getSsn() {
return ssn;
}
public String getName() {
return name;
}
int id;
String ssn;
String name;
public User(int id, String ssn, String name) {
this.id = id;
this.ssn = ssn;
this.name = name;
}
}
Update: Updated List<User>
to List<Object>
.
It’s not necessarily an improvement over a loop solution but you can solve the task using the Stream API like this:
Map<String, List<Object>> result = users.stream()
.collect(Collectors.teeing(
Collectors.mapping(User::getId, Collectors.toList()),
Collectors.mapping(User::getSsn, Collectors.toList()),
(id, ssn) -> Map.of("IDs", id, "SSNs", ssn)));
Above example works with Eclipse. It seems, javac has problems with the type inference. The following works on both:
Map<String, List<Object>> result = users.stream()
.collect(Collectors.teeing(
Collectors.mapping(User::getId, Collectors.<Object>toList()),
Collectors.mapping(User::getSsn, Collectors.<Object>toList()),
(id, ssn) -> Map.of("IDs", id, "SSNs", ssn)));
Alternatively
Map<String, List<?>> result = users.stream()
.collect(Collectors.teeing(
Collectors.mapping(User::getId, Collectors.toList()),
Collectors.mapping(User::getSsn, Collectors.toList()),
(id, ssn) -> Map.of("IDs", id, "SSNs", ssn)));