I have Following use case:
User Object is as followed:
UserId payload
123 abc1
123 abc2
456 pqr1
456 pqr2
678 xyz1
And after iterating above list<User Object>, Result should be like:
{123=[abc1, abc2], 456=[pqr1,pqr2], 678=[xyz1]}
so that I can use value(list of other objects) for key(123) for further processing. What will be best way to do it?
I have tried below but not sure how performance efficient if object size increases.
Map<String,List<String>> userMap = new HashMap<String, List<String>>();
for(User user: users) {
String userId = user.getUserId();
List<String> payloads = new ArrayList<String>();
if(userMap.containsKey(userId)) {
payload = userMap.get(userId);
payloads.add(user.getPayload());
userMap.put(userId, payloads);
}
else {
payloads.add(user.getPayload());
userMap.put(user.getUserId(), payloads);
}
}
-
You should only create a new ArrayList if you need one. And you should not put the list if it's already in the map. And you can just call get() and check if the value is null instead of using containsKey. But unless you have millions of users, you probably won't notice any difference.JB Nizet– JB Nizet2019年08月13日 18:47:42 +00:00Commented Aug 13, 2019 at 18:47
-
You could also use Streams and their groupingBy collector to make the code simpler. Which what you should aim for, rather than performance.JB Nizet– JB Nizet2019年08月13日 18:48:36 +00:00Commented Aug 13, 2019 at 18:48
2 Answers 2
The easiest way would be to stream
the List
and use Collectors#groupingBy
and Collectors#mapping
:
Map<String, List<String>> userMap = users.stream()
.collect(Collectors.groupingBy(User::getUserId,
Collectors.mapping(User::getPayload, Collectors.toList())));
Output:
{123=[abc1, abc2], 456=[pqr1, pqr2], 678=[xyz1]}
answered Aug 13, 2019 at 18:48
Another possible solution would be to use Guavas Maps.toMap
answered Aug 13, 2019 at 18:51
lang-java